home *** CD-ROM | disk | FTP | other *** search
/ WarCraft 2000 - Nuclear Epidemic / W2000.nrg / SOURCE.War2000 / walls.cpp < prev    next >
C/C++ Source or Header  |  1998-09-17  |  18KB  |  757 lines

  1. //walls discription and building
  2. #include "ddini.h"
  3. #include "ResFile.h"
  4. #include "FastDraw.h"
  5. #include "mgraph.h"
  6. #include "mouse.h"
  7. #include "menu.h"
  8. #include "MapDiscr.h"
  9. #include "multipl.h"
  10. #include "mode.h"
  11. #include "fog.h"
  12. #include "walls.h"
  13. #include "3DSurf.h"
  14. #include <assert.h>
  15. const int drrf[9]={7,6,5,0,0,4,1,2,3};
  16. extern byte tiles[32][8192];
  17. extern bool EditMapMode;
  18. int NDWalls;
  19. int NDWBUF[8];
  20. word Links[256][256];
  21. word LIndex[256][256];
  22. WallDiscr Walls[2];
  23. //GLOBAL WALLS SYSTEM
  24. GWSys GWALLS;
  25. void LoadWalls(){
  26.     char gg[128];
  27.     FILE* f=fopen("info.dat","r");
  28.     for(int i=0;i<2;i++){
  29.         fscanf(f,"%s",gg);
  30.         for(int j=0;j<3;j++)
  31.             for(int k=0;k<16;k++)
  32.                 fscanf(f,"%d",&Walls[i].All[j*16+k]);
  33.     };
  34.     fscanf(f,"%s",gg);
  35.     for(i=0;i<8;i++)fscanf(f,"%d",&NDWBUF[i]);
  36.     fclose(f);
  37.     memset(Links,255,sizeof Links);
  38.     memset(LIndex,255,sizeof LIndex);
  39. };
  40. WallCluster::WallCluster(){
  41.     ClusterSize=0;
  42.     Cells=NULL;
  43.     OwnerID=0;
  44.     Type=0;
  45. };
  46. int WallCluster::CheckPoint(byte x,byte y){
  47.     if(Cells==NULL)return -1;
  48.     for(int i=0;i<ClusterSize;i++){
  49.         WallCell* WC=&Cells[i];
  50.         if(x==WC->x&&y==WC->y)return i;
  51.     };
  52.     return -1;
  53. };
  54. void WallCluster::PreArrangeTiles(){
  55.     if(ClusterSize==0)return;
  56.     word* tm=new word[ClusterSize];
  57.     for(int i=0;i<ClusterSize;i++){
  58.         WallCell* WC=&Cells[i];
  59.         tm[i]=Links[WC->y][WC->x];
  60.         Links[WC->y][WC->x]=1956;
  61.     };
  62.     for(i=0;i<ClusterSize;i++){
  63.         WallCell* WC=&Cells[i];
  64.         int dd=0;
  65.         if(Links[WC->y+1][WC->x]==1956)dd=1;
  66.         if(Links[WC->y][WC->x+1]==1956)dd+=2;
  67.         if(Links[WC->y-1][WC->x]==1956)dd+=4;
  68.         if(Links[WC->y][WC->x-1]==1956)dd+=8;
  69.         WC->Tile=Walls[1].Good[dd];
  70.     };
  71.     for(i=0;i<ClusterSize;i++){
  72.         WallCell* WC=&Cells[i];
  73.         Links[WC->y][WC->x]=tm[i];
  74.     };
  75.     free(tm);
  76. };
  77. void WallCluster::ArrangeTiles(){
  78.     if(ClusterSize==0)return;
  79.     word wci=Index;
  80.     for(int i=0;i<ClusterSize;i++){
  81.         WallCell* WC=&Cells[i];
  82.         int dd=0;
  83.         if(Links[WC->y+1][WC->x]==wci)dd=1;
  84.         if(Links[WC->y][WC->x+1]==wci)dd+=2;
  85.         if(Links[WC->y-1][WC->x]==wci)dd+=4;
  86.         if(Links[WC->y][WC->x-1]==wci)dd+=8;
  87.         WC->Tile=Walls[1].All[(WC->Stage<<4)+dd];
  88.         word tt=tmap[WC->x-1][WC->y-1];
  89.         if(WC->Health&&tt!=(char)WC->Tile){
  90.             tmap[WC->x-1][WC->y-1]=(char)WC->Tile;
  91.             ClearRender(WC->x,WC->y);
  92.         };
  93.     };
  94. };
  95.  
  96. bool ChkWTile(int til){
  97.     if(til!=0&&til!=1&&(til<162||til>176)&&(til<178||til>192))return false;
  98.     else return true;
  99. }
  100. void WallCluster::AddWall(byte x,byte y){
  101.     int til=tmap[x-1][y-1];
  102.     if(TrMap[y][x])return;
  103.     if(!ChkWTile(til))return;
  104.     int zz=CheckPoint(x,y);
  105.     if(zz!=-1){
  106.         ClusterSize=zz+1;
  107.         PreArrangeTiles();
  108.         return;
  109.     };
  110.     WallCell* WCL=new WallCell[ClusterSize+1];
  111.     if(int(Cells)){
  112.         WallCell* WOL=Cells;
  113.         memcpy(WCL,WOL,ClusterSize*sizeof WallCell);
  114.         free(Cells);
  115.     };
  116.     Cells=WCL;
  117.     WCL=&Cells[ClusterSize];
  118.     ClusterSize++;
  119.     WCL->x=x;
  120.     WCL->y=y;
  121.     WCL->Stage=2;
  122.     WCL->Health=1;
  123.     PreArrangeTiles();
  124. };
  125. extern byte mtiles[16][4096];
  126. void WallCluster::ShowCluster(){
  127.     if(MiniMode){
  128.         for(int i=0;i<ClusterSize;i++){
  129.             WallCell* WC=&Cells[i];
  130.             byte x=WC->x;
  131.             byte y=WC->y;
  132.             if(x>=mapx&&y>=mapy&& x<mapx+smaplx&&y<mapy+smaply){
  133.                 int tofs=int(mtiles)+256*WC->Tile;
  134.                 int    sofs=int(ScreenPtr)+smapx+(int(x-mapx)<<4)+
  135.                     ((int(y-mapy)<<4)+smapy)*SCRSizeX;
  136.                 int    Addo=SCRSizeX-16;
  137.                 __asm{
  138.                     cld
  139.                     mov        esi,tofs
  140.                     mov        edi,sofs
  141.                     mov        ecx,16
  142. iii:                movsd
  143.                     movsd    
  144.                     movsd
  145.                     movsd
  146.                     add        edi,Addo
  147.                     loop    iii
  148.                 };
  149.             };
  150.         };
  151.         return;
  152.     };
  153.     for(int i=0;i<ClusterSize;i++){
  154.         WallCell* WC=&Cells[i];
  155.         byte x=WC->x;
  156.         byte y=WC->y;
  157.         if(x>=mapx&&y>=mapy&& x<mapx+smaplx&&y<mapy+smaply){
  158.             int tofs=int(tiles)+1024*WC->Tile;
  159.             int    sofs=int(ScreenPtr)+smapx+(int(x-mapx)<<5)+
  160.                 ((int(y-mapy)<<5)+smapy)*SCRSizeX;
  161.             int    Addo=SCRSizeX-32;
  162.             __asm{
  163.                 cld
  164.                 mov        esi,tofs
  165.                 mov        edi,sofs
  166.                 mov        ecx,32
  167. ziii:            movsd
  168.                 movsd    
  169.                 movsd
  170.                 movsd
  171.                 movsd
  172.                 movsd
  173.                 movsd
  174.                 movsd
  175.                 add        edi,Addo
  176.                 loop    ziii
  177.             };
  178.         };
  179.     };
  180. };
  181. void WallCluster::Stand(){
  182.  
  183. };
  184. int CheckNeed(byte x,byte y,word LNK1){
  185.     word LNK=Links[y][x];
  186.     if(LNK==LNK1&&LNK!=0xFFFF){
  187.         WallCluster* WC=&GWALLS.GWC[LNK];
  188.         WallCell* OC=&WC->Cells[LIndex[y][x]];
  189.         if(OC->Health<OC->MaxHealth)return LIndex[y][x];
  190.     };
  191.     return -1;
  192. };
  193. int CheckDNeed(byte x,byte y,word LNK1){
  194.     word LNK=Links[y][x];
  195.     if(LNK==LNK1&&LNK!=0xFFFF){
  196.         WallCluster* WC=&GWALLS.GWC[LNK];
  197.         WallCell* OC=&WC->Cells[LIndex[y][x]];
  198.         return LIndex[y][x];
  199.     };
  200.     return -1;
  201. };
  202. int WallCluster::FindWorkPoint(byte x,byte y,word ID){
  203.     int xx=x;
  204.     int    yy=y;
  205.     int dis=1000;
  206.     int lp=-1;
  207.     WallCell* WW;
  208.     int rr=CheckNeed(xx+1,yy,Index);
  209.     if(rr!=-1)return rr;
  210.     rr=CheckNeed(xx-1,yy,Index);
  211.     if(rr!=-1)return rr;
  212.     rr=CheckNeed(xx,yy+1,Index);
  213.     if(rr!=-1)return rr;
  214.     rr=CheckNeed(xx+1,yy,Index);
  215.     if(rr!=-1)return rr;
  216.     rr=CheckNeed(xx+1,yy+1,Index);
  217.     if(rr!=-1)return rr;
  218.     rr=CheckNeed(xx+1,yy-1,Index);
  219.     if(rr!=-1)return rr;
  220.     rr=CheckNeed(xx-1,yy-1,Index);
  221.     if(rr!=-1)return rr;
  222.     rr=CheckNeed(xx-1,yy+1,Index);
  223.     if(rr!=-1)return rr;
  224.     for(int i=0;i<ClusterSize;i++){
  225.         WallCell* WC=&Cells[i];
  226.         if(WC->Stage!=32&&WC->WorkNeed>0&&(WC->WorkTime==0||WC->WorkerID==ID)){
  227.             int dis1=abs(xx-WC->x)+abs(yy-WC->y)/*+((WC->MaxHealth-WC->Health)>>7)*/;
  228.             if(dis1<dis){
  229.                 lp=i;
  230.                 dis=dis1;
  231.                 WW=WC;
  232.             };
  233.         };
  234.     };
  235.     if(lp==-1){
  236.         for(int i=0;i<ClusterSize;i++){
  237.             WallCell* WC=&Cells[i];
  238.             if(WC->Stage!=32&&WC->WorkNeed>0){
  239.                 int dis1=abs(xx-WC->x)+abs(yy-WC->y)/*+((WC->MaxHealth-WC->Health)>>7)*/;
  240.                 if(dis1<dis){
  241.                     lp=i;
  242.                     dis=dis1;
  243.                     WW=WC;
  244.                 };
  245.             };
  246.         };
  247.     };
  248.     if(lp!=-1){
  249.         WW->WorkerID=ID;
  250.         WW->WorkTime+=5;
  251.     };
  252.     return lp;
  253. };
  254. int WallCluster::FindDamagePoint(byte x,byte y,word ID){
  255.     int xx=x;
  256.     int    yy=y;
  257.     int dis=1000;
  258.     int lp=-1;
  259.     WallCell* WW;
  260.     int rr=CheckDNeed(xx+1,yy,Index);
  261.     if(rr!=-1)return rr;
  262.     rr=CheckDNeed(xx-1,yy,Index);
  263.     if(rr!=-1)return rr;
  264.     rr=CheckDNeed(xx,yy+1,Index);
  265.     if(rr!=-1)return rr;
  266.     rr=CheckDNeed(xx+1,yy,Index);
  267.     if(rr!=-1)return rr;
  268.     rr=CheckDNeed(xx+1,yy+1,Index);
  269.     if(rr!=-1)return rr;
  270.     rr=CheckDNeed(xx+1,yy-1,Index);
  271.     if(rr!=-1)return rr;
  272.     rr=CheckDNeed(xx-1,yy-1,Index);
  273.     if(rr!=-1)return rr;
  274.     rr=CheckDNeed(xx-1,yy+1,Index);
  275.     if(rr!=-1)return rr;
  276.     for(int i=0;i<ClusterSize;i++){
  277.         WallCell* WC=&Cells[i];
  278.         if(WC->Stage!=32&&WC->DamNeed>0&&(WC->WorkTime==0||WC->WorkerID==ID)){
  279.             int dis1=abs(xx-WC->x)+abs(yy-WC->y);
  280.             if(dis1<dis){
  281.                 lp=i;
  282.                 dis=dis1;
  283.                 WW=WC;
  284.             };
  285.         };
  286.     };
  287.     if(lp==-1){
  288.         for(int i=0;i<ClusterSize;i++){
  289.             WallCell* WC=&Cells[i];
  290.             if(WC->Stage!=32&&WC->DamNeed>0){
  291.                 int dis1=abs(xx-WC->x)+abs(yy-WC->y);
  292.                 if(dis1<dis){
  293.                     lp=i;
  294.                     dis=dis1;
  295.                     WW=WC;
  296.                 };
  297.             };
  298.         };
  299.     };
  300.     if(lp!=-1){
  301.         WW->WorkerID=ID;
  302.         WW->WorkTime+=5;
  303.     };
  304.     return lp;
  305. };
  306. void WallCluster::Init(){
  307.     if(Cells)free(Cells);
  308.     Cells=NULL;
  309.     ClusterSize=0;
  310. };
  311. int WallCluster::GetDataSize(){
  312.     return 4+2*ClusterSize;
  313. };
  314. //data format: [kind][owner][count:16][x1][y1][x2][y2]...
  315. void WallCluster::CreateData(byte NI,byte* lpData){
  316.      byte* db=lpData;
  317.      word* dw=(word*) lpData;
  318.      db[0]=Type;
  319.      db[1]=NI;
  320.      dw[1]=word(ClusterSize);
  321.      db+=4;
  322.      for(int i=0;i<ClusterSize;i++){
  323.          WallCell* WC=&Cells[i];
  324.          db[0]=WC->x;
  325.          db[1]=WC->y;
  326.          db+=2;
  327.      };
  328. };
  329. //Sample of cluster
  330. WallCluster TMPCluster;
  331. bool BuildWall;
  332. bool WStarted;
  333. void SetBuildWallMode(){
  334.     BuildWall=true;
  335.     WStarted=false;
  336.     TMPCluster.Init();
  337. };
  338. bool ManualFogCheck(int x,int y,int dx);
  339. void WallHandleMouse(int x,int y){
  340.     int SHF=5;
  341.     if(MiniMode)SHF=4;
  342.     if(x<smapx||y<smapy||x>=smapx+(smaplx<<SHF)||y>=smapy+(smaply<<SHF))return;
  343.     if(BuildWall){
  344.         if(Lpressed&&!WStarted)WStarted=true;
  345.         if(WStarted){
  346.             int xxx=mapx+((x-smapx)>>SHF);
  347.             int yyy=mapy+((y-smapy)>>SHF);
  348.             if(EditMapMode)TMPCluster.AddWall(xxx,yyy);
  349.             else if(fmap[yyy][xxx]>2000)
  350.                 TMPCluster.AddWall(xxx,yyy);
  351.         };
  352.         if(WStarted&&!Lpressed){
  353.             BuildWall=false;
  354.             CmdBuildWall(MyNation);
  355.         };
  356.     };
  357. };
  358.  
  359. GWSys::GWSys(){
  360.     MaxWall=1024;
  361.     GWC=new WallCluster[MaxWall];
  362.     memset(GWC,0,MaxWall*sizeof WallCluster);
  363. };
  364. //data format: [kind][owner][count:16][x1][y1][x2][y2]...
  365. word GWSys::AddCluster(byte* Data){
  366.     for(int i=0;i<MaxWall&&GWC[i].ClusterSize;i++);
  367.     if(i>=MaxWall){
  368.         WallCluster* OWC=GWC;
  369.         GWC=new WallCluster[MaxWall+1024];
  370.         memcpy(GWC,OWC,MaxWall*sizeof WallCluster);
  371.         memset(&GWC[MaxWall],0,1024*sizeof WallCluster);
  372.         i=MaxWall;
  373.         MaxWall+=1024;
  374.         free(OWC);
  375.     };
  376.     WallCluster* WC=&GWC[i];
  377.     word CLIN=i;
  378.     byte* db=Data;
  379.     word* dw=(word*)Data;
  380.     WC->Type=db[0];
  381.     WC->OwnerID=db[1];
  382.     WC->ClusterSize=int(dw[1]);
  383.     WC->Index=CLIN;
  384.     WC->Cells=new WallCell[WC->ClusterSize];
  385.     WallCell* OC=WC->Cells;
  386.     db+=4;
  387.     for(i=0;i<WC->ClusterSize;i++){
  388.         OC->x=db[0];
  389.         OC->y=db[1];
  390.         OC->Stage=2;
  391.         OC->Health=1;
  392.         OC->MaxHealth=16000;
  393.         OC->WorkTime=0;
  394.         OC->WorkerID=0xFFFF;
  395.         OC->BuildProgress=1;
  396.         Links[OC->y][OC->x]=CLIN;
  397.         LIndex[OC->y][OC->x]=i;
  398.         if(Mops[OC->y][OC->x]==0xFFFF){
  399.             LLock[OC->y][OC->x]=1;
  400.             IncLock(OC->x,OC->y);
  401.             TrMap[OC->y][OC->x]=1;
  402.         };
  403.         OC++;
  404.         db+=2;
  405.     };
  406.     OC=WC->Cells;
  407.     WC->ArrangeTiles();
  408.     for(i=0;i<WC->ClusterSize;i++){
  409.         if(OC->Health)tmap[OC->x-1][OC->y-1]=(char)OC->Tile;
  410.         ClearRender(OC->x,OC->y);
  411.         OC++;
  412.     };
  413.     return CLIN;
  414. };
  415. void GWSys::ProcessClusters(){
  416.     WallCluster* WC=GWC;
  417.     bool TTF,NNT;
  418.     for(int i=0;i<MaxWall;i++){
  419.         if(WC->OwnerID==MyNation)NNT=true;else NNT=false;
  420.         if(WC->ClusterSize!=0){
  421.             WallCell* OC=WC->Cells;
  422.             TTF=false;
  423.             int j=WC->ClusterSize;
  424.             for(int k=0;k<j;k++){
  425.                 if(NNT)fmap[OC->y][OC->x]=10000;
  426.                 word MID=Mops[OC->y][OC->x];
  427.                 if(MID!=0xFFFF){
  428.                     OneObject* OB=Group[MID];
  429.                     if(OB){
  430.                         OB->MoveFrom(0);
  431.                     };
  432.                 }else{
  433.                     if(OC->Health){
  434.                         LLock[OC->y][OC->x]=1;
  435.                         IncLock(OC->x,OC->y);
  436.                         TrMap[OC->y][OC->x]=1;
  437.                     };
  438.                 };
  439.                 if(OC->Health>=OC->MaxHealth)OC->WorkNeed=0;
  440.                 {
  441.                     byte xx=OC->x;
  442.                     byte yy=OC->y;
  443.                     byte wn=0;
  444.                     _asm{
  445.                         xor        eax,eax
  446.                         xor        ebx,ebx
  447.                         mov        bl,xx
  448.                         mov        bh,yy
  449.                         cmp        byte ptr [LLock+ebx-256],0
  450.                         jnz        rtr1
  451.                         inc        eax
  452. rtr1:                    cmp        byte ptr [LLock+ebx-255],0
  453.                         jnz        rtr2
  454.                         inc        eax
  455. rtr2:                    cmp        byte ptr [LLock+ebx+1],0
  456.                         jnz        rtr3
  457.                         inc        eax
  458. rtr3:                    cmp        byte ptr [LLock+ebx+257],0
  459.                         jnz        rtr4
  460.                         inc        eax
  461. rtr4:                    cmp        byte ptr [LLock+ebx+256],0
  462.                         jnz        rtr5
  463.                         inc        eax
  464. rtr5:                    cmp        byte ptr [LLock+ebx+255],0
  465.                         jnz        rtr6
  466.                         inc        eax
  467. rtr6:                    cmp        byte ptr [LLock+ebx-1],0
  468.                         jnz        rtr7
  469.                         inc        eax
  470. rtr7:                    cmp        byte ptr [LLock+ebx-257],0
  471.                         jnz        rtr8
  472.                         inc        eax
  473. rtr8:                    mov        wn,al
  474.                     };
  475.                     if(OC->Health>=OC->MaxHealth)OC->WorkNeed=0;
  476.                     else OC->WorkNeed=wn;
  477.                     OC->DamNeed=wn;
  478.                     if(OC->WorkTime>0)OC->WorkTime--;
  479.                     if(OC->WorkTime==0)OC->WorkerID=0xFFFF;
  480.                     if(OC->Health==0&&OC->Stage!=32){
  481.                         Links[OC->y][OC->x]=0xFFFF;
  482.                         LLock[OC->y][OC->x]=0;
  483.                         DecLock(OC->x,OC->y);
  484.                         TrMap[OC->y][OC->x]=0;
  485.                         OC->Stage=32;
  486.                     };
  487.                 };
  488.                 OC++;
  489.             };
  490.         };
  491.         WC->ArrangeTiles();
  492.         WC++;
  493.     };
  494. };
  495. void GWSys::DamageCell(byte x,byte y,byte Owner,word Incr){
  496.     word LID=Links[y][x];
  497.     if(LID==0xFFFF)return;
  498.     WallCluster* WC=&GWC[LID];
  499. //    if(WC->OwnerID!=Owner)return;
  500.     word CID=LIndex[y][x];
  501.     if(CID>WC->ClusterSize)return;
  502.     WallCell* OC=&WC->Cells[CID];
  503.     OC->BuildProgress+=Incr;
  504.     if(OC->Health>=Incr)OC->Health-=Incr;else OC->Health=0;
  505.     if(OC->Stage==0&&OC->Health<=(OC->MaxHealth>>1))OC->Stage=1;
  506.     int dd=0;
  507.     //if(Links[y+1][x]!=0xFFFF)dd+=1;
  508.     //if(Links[y][x+1]!=0xFFFF)dd+=2;
  509.     //if(Links[y-1][x]!=0xFFFF)dd+=4;
  510.     //if(Links[y][x-1]!=0xFFFF)dd+=8;
  511.     if(OC->Health==0){
  512.         OC->Tile=rando()&1;//NDWBUF[rando()&7];
  513.         tmap[x-1][y-1]=(byte)OC->Tile;
  514.         ClearRender(x,y);
  515.         //TrMap[y][x]=0;
  516.         //LLock[y][x]=0;
  517.     };
  518. };
  519. void GWSys::BuildCell(byte x,byte y,byte Owner,byte xIncr,word WorkerID){
  520.     word Incr=xIncr;
  521.     if(EditMapMode)Incr=8000;else Incr=xIncr<<4;
  522.     word LID=Links[y][x];
  523.     if(LID==0xFFFF)return;
  524.     WallCluster* WC=&GWC[LID];
  525.     if(WC->OwnerID!=Owner)return;
  526.     word CID=LIndex[y][x];
  527.     if(CID>WC->ClusterSize)return;
  528.     WallCell* OC=&WC->Cells[CID];
  529.     OC->BuildProgress+=Incr;
  530.     OC->WorkerID=WorkerID;
  531.     OC->WorkTime=20;
  532.     if(OC->Health+Incr<OC->MaxHealth)OC->Health+=Incr;
  533.     else OC->Health=OC->MaxHealth;
  534.     if(OC->Stage==1&&OC->Health>=OC->MaxHealth)OC->Stage=0;
  535.     if(OC->Stage==2&&OC->Health>=(OC->MaxHealth>>1))OC->Stage=1;
  536.     int dd=0;
  537.     if(Links[y+1][x]!=0xFFFF)dd+=1;
  538.     if(Links[y][x+1]!=0xFFFF)dd+=2;
  539.     if(Links[y-1][x]!=0xFFFF)dd+=4;
  540.     if(Links[y][x-1]!=0xFFFF)dd+=8;
  541.     OC->Tile=Walls[WC->Type].All[(OC->Stage<<4)+dd];
  542.     if(OC->Health)tmap[x-1][y-1]=(byte)OC->Tile;
  543. };
  544. void BuildWallLink(OneObject* OBJ);
  545. bool OneObject::BuildWall(word OID,int Prio){
  546.     if(Prio<PrioryLevel)return false;
  547.     if(!capBuild)return false;
  548.     if(capBuilding)return false;
  549.     Important=true;
  550.     Order1* Or1=GetOrdBlock();
  551.     if(!int(Or1))return false;
  552.     //Or1->PrioryLevel=Prio&127;
  553.     Or1->NextOrder=LocalOrder;
  554.     Or1->OrderType=227;//Build wall
  555.     Or1->OrderTime=0;
  556.     Or1->DoLink=&BuildWallLink;
  557.     Or1->info.MoveToObj.ObjIndex=OID;
  558.     Order1* LOR=LocalOrder;
  559.     if(int(InLineCom))FreeAsmLink();
  560.     LocalOrder=Or1;
  561.     //OrderReport=NULL;
  562.     //MessageKind=0;
  563.     //Sender=0xFFFF;
  564.     PrioryLevel=Prio&127;
  565.     return true;
  566. };    
  567. void FindEmptyPoint(byte* x,byte* y){
  568.     byte xx=*x;
  569.     byte yy=*y;
  570.     __asm{
  571.         xor        eax,eax
  572.         mov        al,xx
  573.         mov        ah,yy
  574.         add        eax,offset LLock
  575.         cmp        byte ptr [eax-256],0
  576.         jne        dr_1
  577.         dec        yy
  578.         jmp        dr_end
  579. dr_1:    
  580.         cmp        byte ptr [eax+1],0
  581.         jne        dr_2
  582.         inc        xx
  583.         jmp        dr_end
  584. dr_2:
  585.         cmp        byte ptr [eax+256],0
  586.         jne        dr_3
  587.         inc        yy
  588.         jmp        dr_end
  589. dr_3:
  590.         cmp        byte ptr [eax-1],0
  591.         jne        dr_4
  592.         dec        xx
  593.         jmp        dr_end
  594. dr_4:
  595.         cmp        byte ptr [eax-255],0
  596.         jne        dr_5
  597.         inc        xx
  598.         dec        yy
  599.         jmp        dr_end
  600. dr_5:
  601.         cmp        byte ptr [eax+257],0
  602.         jne        dr_6
  603.         inc        yy
  604.         inc        xx
  605.         jmp        dr_end
  606. dr_6:
  607.         cmp        byte ptr [eax+255],0
  608.         jne        dr_7
  609.         dec        xx
  610.         inc        yy
  611.         jmp        dr_end
  612. dr_7:
  613.         cmp        byte ptr [eax-257],0
  614.         jne        dr_8
  615.         dec        yy
  616.         dec        xx
  617.         jmp        dr_end
  618. dr_8:    mov        xx,0
  619.         mov        yy,0;
  620. dr_end:
  621.     };
  622.     *x=xx;
  623.     *y=yy;
  624. };
  625. void BuildWallLink(OneObject* OBJ){
  626.     word OID=OBJ->LocalOrder->info.MoveToObj.ObjIndex;
  627.     WallCluster* WC=&GWALLS.GWC[OID];
  628.     int wi=WC->FindWorkPoint(OBJ->x,OBJ->y,OBJ->Index);
  629.     if(wi==-1)return;
  630.     OBJ->Important=true;
  631.     Order1* Or1;
  632.     TrMap[OBJ->y][OBJ->x]=0;
  633.     if(wi==-1){
  634.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  635.         if(int(OBJ->LocalOrder)){
  636.             Or1=OBJ->LocalOrder->NextOrder;
  637.             OBJ->FreeOrdBlock(OBJ->LocalOrder);
  638.             OBJ->LocalOrder=Or1;
  639.             OBJ->Important=false;
  640.             return;
  641.         };
  642.     };
  643.     WallCell* OC=&WC->Cells[wi];
  644.     int x0=OC->x;
  645.     int y0=OC->y;
  646.     int sx=x0-OBJ->x;
  647.     int    sy=y0-OBJ->y;
  648.     int dx=abs(sx);
  649.     int dy=abs(sy);
  650.     int dst;
  651.     if(dx>dy)dst=dx;
  652.             else dst=dy;
  653.     if(dst<2){
  654.         OBJ->FreeAsmLink();
  655.         OBJ->Direction=drrf[(sx+1)*3+sy+1];
  656.         OBJ->LoadAnimation(2,2,0);
  657.         OBJ->LoadCurAnm(2);
  658.         GWALLS.BuildCell(x0,y0,OBJ->NNUM,250,OBJ->Index);
  659.         OBJ->isMoving=false;
  660.         TrMap[OBJ->y][OBJ->x]=1;
  661.     }else if(!int(OBJ->InLineCom)){
  662.         byte xx=byte(x0);
  663.         byte yy=byte(y0);
  664.         FindEmptyPoint(&xx,&yy);
  665.         if(xx>0)OBJ->CreateSimplePath(xx,yy);
  666.     };
  667. };
  668. bool SearchWall(int* x,int* y){
  669.     int xx=*x;
  670.     int yy=*y;
  671.     int x1,y1;
  672.     for(int i=0;i<8;i++){
  673.         x1=xx+(rando()&31)-16;
  674.         y1=yy+(rando()&31)-16;
  675.         if(x1>0&&y1>0&&x1<msx&&y1<msy){
  676.             if(Links[y1][x1]!=0xFFFF){
  677.                 *x=x1;
  678.                 *y=y1;
  679.                 return true;
  680.             };
  681.         };
  682.     };
  683.     return false;
  684. };
  685. void HandleDWall(OneObject* OB){
  686.     int xx=OB->x;
  687.     int yy=OB->y;
  688.     if(SearchWall(&xx,&yy)){
  689.         OB->ContinueAttackWall(xx,yy,128);
  690.     };
  691. };
  692. void DamageWallLink(OneObject* OBJ);
  693. bool OneObject::DamageWall(word OID,int Prio){
  694.     if(Prio<PrioryLevel)return false;
  695.     if(Ref.Visual->info.Basic.AttackRange>1)return false;
  696.     if(capBuilding)return false;
  697.     Important=true;
  698.     Order1* Or1=GetOrdBlock();
  699.     if(!int(Or1))return false;
  700.     Or1->PrioryLevel=Prio&127;
  701.     Or1->NextOrder=LocalOrder;
  702.     Or1->OrderType=228;//destroy wall
  703.     Or1->OrderTime=0;
  704.     Or1->DoLink=&DamageWallLink;
  705.     Or1->info.MoveToObj.ObjIndex=OID;
  706.     Order1* LOR=LocalOrder;
  707.     if(int(InLineCom))FreeAsmLink();
  708.     LocalOrder=Or1;
  709.     //OrderReport=NULL;
  710.     //MessageKind=0;
  711.     //Sender=0xFFFF;
  712.     PrioryLevel=Prio&127;
  713.     return true;
  714. };
  715. void DamageWallLink(OneObject* OBJ){
  716.     word OID=OBJ->LocalOrder->info.MoveToObj.ObjIndex;
  717.     WallCluster* WC=&GWALLS.GWC[OID];
  718.     int wi=WC->FindDamagePoint(OBJ->x,OBJ->y,OBJ->Index);
  719.     if(wi==-1)return;
  720.     OBJ->Important=true;
  721.     Order1* Or1;
  722.     TrMap[OBJ->y][OBJ->x]=0;
  723.     if(wi==-1){
  724.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  725.         if(int(OBJ->LocalOrder)){
  726.             Or1=OBJ->LocalOrder->NextOrder;
  727.             OBJ->FreeOrdBlock(OBJ->LocalOrder);
  728.             OBJ->LocalOrder=Or1;
  729.             OBJ->Important=false;
  730.             return;
  731.         };
  732.     };
  733.     WallCell* OC=&WC->Cells[wi];
  734.     int x0=OC->x;
  735.     int y0=OC->y;
  736.     int sx=x0-OBJ->x;
  737.     int    sy=y0-OBJ->y;
  738.     int dx=abs(sx);
  739.     int dy=abs(sy);
  740.     int dst;
  741.     if(dx>dy)dst=dx;
  742.             else dst=dy;
  743.     if(dst<2){
  744.         OBJ->FreeAsmLink();
  745.         OBJ->Direction=drrf[(sx+1)*3+sy+1];
  746.         OBJ->LoadAnimation(2,2,0);
  747.         OBJ->LoadCurAnm(2);
  748.         GWALLS.DamageCell(x0,y0,OBJ->NNUM,250);
  749.         OBJ->isMoving=false;
  750.         TrMap[OBJ->y][OBJ->x]=1;
  751.     }else if(!int(OBJ->InLineCom)){
  752.         byte xx=byte(x0);
  753.         byte yy=byte(y0);
  754.         FindEmptyPoint(&xx,&yy);
  755.         if(xx>0)OBJ->CreateSimplePath(xx,yy);
  756.     };
  757. };