home *** CD-ROM | disk | FTP | other *** search
/ WarCraft 2000 - Nuclear Epidemic / W2000.nrg / SOURCE.War2000 / Water.cpp < prev    next >
C/C++ Source or Header  |  1998-09-21  |  46KB  |  2,114 lines

  1. //Floating modules discription & management
  2. //Need to rewrite:
  3. //CreatePath      --->    CreateWPath
  4. //
  5. #include "ddini.h"
  6. #include "ResFile.h"
  7. #include "FastDraw.h"
  8. #include "mgraph.h"
  9. #include "mouse.h"
  10. #include "menu.h"
  11. #include "MapDiscr.h"
  12. #include "multipl.h"
  13. #include "fog.h"
  14. #include "walls.h"
  15. #include "Nature.h"
  16. #include "Megapolis.h"
  17. #include <assert.h>
  18. #include "GSound.h"
  19. extern byte Locking[1024];//╚φ⌠. ε ßδεΩΦ≡εΓαφΦΦ ∩εΓσ≡⌡φε±≥Φ
  20. //extern MaxReplyDistance;
  21. extern int PathAsks;
  22. extern OneObject OBJECTS[8192];
  23. const int drrw[9]={7,6,5,0,0,4,1,2,3};
  24. const byte drrbw[9]={7,6,5,0,0,4,1,2,3};
  25. const int idrxw[8]={0,1,1,1,0,-1,-1,-1};
  26. const int idryw[8]={-1,-1,0,1,1,1,0,-1};
  27. byte WLock[256][256];//Water locking map
  28. byte WMap[256][256];//Static locking map
  29. void CreateWaterMap(){
  30.     for(int i=0;i<msx;i++)for(int j=0;j<msy;j++){
  31.         byte k=Locking[tmap[j][i]];
  32.         if(k&2){
  33.             WLock[i+1][j+1]=1;
  34.             WMap[i+1][j+1]=1;
  35.         };
  36.         //if(k&2)map[j][i].WaterLock=true;
  37.     };
  38.     for(i=0;i<=msx+1;i++){
  39.         WMap[i][0]=2;
  40.         WMap[i][msy+2]=2;
  41.         WLock[i][0]=2;
  42.         WLock[i][msy+2]=2;
  43.         WMap[i][0]=2;
  44.         WMap[i][msy+1]=2;
  45.         WLock[i][0]=2;
  46.         WLock[i][msy+1]=2;
  47.  
  48.     };
  49.     for(i=0;i<msy+1;i++){
  50.         WMap[0][i]=2;
  51.         WMap[msx+2][i]=2;
  52.         WLock[0][i]=2;
  53.         WLock[msx+2][i]=2;
  54.         WMap[0][i]=2;
  55.         WMap[msx+1][i]=2;
  56.         WLock[0][i]=2;
  57.         WLock[msx+1][i]=2;
  58.     };
  59. };
  60.  
  61. struct AskMove{
  62.     word ReqID;//ΦφΣσΩ± ∩σ≡σ∞σ∙ασ∞επε
  63.     word PreID;//ΦφΣσΩ± µαµΣ≤∙σπε Σε≡Γα≥ⁿ±  Γ ²≥≤ Ωδσ≥Ω≤
  64.     byte x;
  65.     byte y;
  66.     char dx;
  67.     char dy;
  68. };
  69. extern int NAsk;//╩εδΦ≈σ±≥Γε τα∩≡ε±εΓ
  70. extern AskMove Ask[8192];//╠α±±ΦΓ τα∩≡ε±εΓ
  71. extern bool FailLink[8192];//╠α±±ΦΓ φσ≡ατ≡σ°σφφ√⌡ ∩σ≡σ∞σ∙σφΦΘ
  72. extern word CurInd;
  73. extern word IDMap[256][256];
  74. extern word RQMap[256][256];//:3-τα∩σ∙σφφεσ φα∩≡αΓδσφΦσ ..
  75.                      //:13-φε∞σ≡ Γ ≥αßδΦ÷σ τα∩≡ε±εΓ
  76. //─εßαΓΦ≥ⁿ τα∩≡ε± Γ ±Φ±≥σ∞≤ τα∩≡ε±εΓ φα ∩σ≡σ∞σ∙σφΦσ
  77. void AddWAsk(word ReqID,byte x,byte y,char zdx,char zdy){
  78.     __asm{
  79. //        inc        NAsk
  80.         mov        eax,NAsk
  81.         shl        eax,3
  82.         add        eax,offset Ask
  83.         mov        bx,ReqID
  84.         mov        word ptr [eax],bx
  85.         mov        word ptr [eax+2],0FFFFh
  86.         mov        bl,x
  87.         mov        bh,y
  88.         mov        word ptr [eax+4],bx
  89.         mov        bl,zdx
  90.         sal            bl,1//moving on 2 cells
  91.         mov        bh,zdy
  92.         sal            bh,1
  93.         mov        word ptr [eax+6],bx
  94.         inc        NAsk
  95.     };
  96. };
  97. //╬ß≡αßε≥Ωα τα∩≡ε±εΓ, ±φα≈αδα ε±ΓεßεµΣασ∞ Γ±σ ±≥α≡√σ Ωδσ≥ΩΦ
  98. //∩ε≥ε∞ τα∩εδφ σ∞ Φ ∩≡εΓσ≡ σ∞
  99. void HandleWAsks(){
  100.     if(!NAsk)return;
  101.     __asm{
  102.         cmp        CurInd,0
  103.         jne        NoFill
  104.         mov        edi,offset IDMap
  105.         mov        ecx,32768
  106.         cld    
  107.         xor        eax,eax
  108.         rep        stosd
  109. NoFill:
  110.         inc        CurInd
  111.     };
  112.     int NN=NAsk;
  113.     int    ZZ=0;
  114.     //ε±ΓεßεµΣασ∞ ∞σ±≥ε
  115.     __asm{
  116.         mov    esi,offset Ask
  117.         xor        eax,eax
  118.         xor        ecx,ecx
  119.         xor        ebx,ebx
  120.         xor        edx,edx
  121. C1Begin:
  122.         mov        al,[esi+6]//dx
  123.         add        al,2
  124.         mov        ah,al
  125.         shr        al,1
  126.         add        al,ah
  127.         mov        ah,[esi+7]//dy
  128.         add        ah,2
  129.         shr        ah,1
  130.         add        al,ah
  131.         xor        ah,ah
  132.         mov        bl,byte ptr [drrbw+eax]//direction
  133.         mov        cx,[esi+4]//x,y=>offset
  134.         mov        ax,CurInd
  135.         mov        [IDMap+ecx*2],ax
  136.         add        bl,4
  137.         and        bl,7
  138.         mov        dx,word ptr ZZ
  139.         shl        dx,3
  140.         add        dl,bl
  141.         mov        [RQMap+ecx*2],dx
  142.         mov        byte ptr [WLock+ecx],0//≡ατßδεΩΦ≡εΓαδΦ ±≥α≡εσ ∩εδεµσφΦσ
  143.         add        esi,8//size of Ask[0] 
  144.         inc        ZZ
  145.         dec        NN
  146.         jnz        C1Begin
  147.         //ε≈Φ∙ασ∞ ∞α±±ΦΓ ±ßεσΓ
  148.         mov        edi,offset FailLink
  149.         mov        ecx,NAsk
  150.         shr        ecx,2
  151.         inc        ecx
  152.         cld
  153.         mov        eax,01010101h
  154.         rep        stosd
  155.         //╧≡εΓσ≡ σ∞ Γετ∞εµφε±≥ⁿ ∩σ≡σ∞σ∙σφΦ 
  156.         mov        eax,NAsk
  157.         mov        NN,eax
  158.         mov        esi,offset Ask
  159.         xor        ecx,ecx
  160.         xor        eax,eax
  161.         mov        ZZ,0
  162. C2Begin:
  163.  
  164.         mov        cx,[esi+4]//x,y -> offset
  165.         add        cl,[esi+6]//x+dx,y+dy -> offset
  166.         add        ch,[esi+7]
  167.         cmp        byte ptr [WLock+ecx],0
  168.         jnz        C2isLocked
  169.         mov        ax,word ptr CurInd
  170.         cmp        word ptr [IDMap+ecx*2],ax
  171.         jne        C2notLocked
  172.         //direction
  173.         mov        dx,[RQMap+ecx*2]
  174.         and        dl,7
  175.         mov        al,[esi+6]
  176.         add        al,2
  177.         mov        ah,al
  178.         shr        al,1
  179.         add        al,ah
  180.         mov        ah,[esi+7]
  181.         add        ah,2
  182.         shr        ah,1
  183.         add        al,ah
  184.         xor        ah,ah
  185.         mov        al,[drrbw+eax]//=direction
  186.         cmp        al,dl
  187.         je        C2isLocked //∩σ≡σ⌡εΣ Γ ²≥ε∞ φα∩≡αΓδσφΦΦ τα∩≡σ∙σφ
  188.         //±≥αΓΦ∞ ±±√δΩ≤ φα Σαφφεπε ∞εφ±≥≡α Γ ∩εδσ PreID 
  189.         //≤ ∞εφ±≥≡α, Ωε≥ε≡√Θ ≡αφσσ ταφΦ∞αδ ²≥≤ Ωδσ≥Ω≤
  190.         mov        dx,[RQMap+ecx*2]
  191.         and        edx,0FFF8h
  192.         mov        ax,word ptr ZZ
  193.         mov        word ptr [Ask+2+edx],ax
  194. C2notLocked:
  195.         mov        [WLock+ecx],1//ßδεΩΦ≡≤σ∞ Ωδσ≥Ω≤
  196.         inc        ZZ
  197.         add        esi,8
  198.         dec        NN
  199.         jnz        C2Begin
  200.         jmp        CycEnd
  201.         //╩δσ≥Ωα ταßδεΩΦ≡εΓαφα, ε∩≡σΣσδ σ∞ ∞εφ±≥≡εΓ,∩σ≡σ∞σ∙σφΦσ 
  202.         //Ωε≥ε≡√⌡ τα∩≡σ∙σφε ε≥φ√φσ
  203. C2isLocked:
  204.         mov        ax,[esi+4]
  205.         mov        byte ptr [WLock+eax],1
  206.         mov        ax,word ptr ZZ
  207.         xor        edx,edx
  208. FailLoop:
  209.         mov        byte ptr [FailLink+eax],0
  210.         mov        bx,word ptr [Ask+2+eax*8]
  211.         mov        word ptr [Ask+2+eax*8],0FFFFh
  212.         mov        dx,word ptr [Ask+4+eax*8]
  213.         mov        [WLock+edx],1//ßδεΩΦ≡≤σ∞ ±≥α≡≤■ ∩ετΦ÷Φ■
  214.         mov        ax,bx
  215.         cmp        ax,0FFFFh
  216.         jne        FailLoop
  217.         inc        ZZ
  218.         add        esi,8
  219.         dec        NN
  220.         jnz        C2Begin
  221. CycEnd:
  222.     };
  223.     //≡στ≤δⁿ≥α≥ε∞ Γ√°σ≤Ωαταφφεπε ∩≡ε±≥≡αΣα ß√δε
  224.     //∩≡αΓΦδⁿφεσ τα∩εδφσφΦσ ∞α±±ΦΓα FailLink,
  225.     //≥ε σ±≥ⁿ ε∩≡σΣσδσφΦσ, ΩαΩΦ∞ ∞εφ±≥≡α∞ ∩σ≡σ∞σ∙σφΦσ 
  226.     //≡ατ≡σ°σφε, α ΩαΩΦ∞ φσ≥
  227. };
  228. inline void WSpot(int x,int y){
  229.     if(x>0&&y>0&&x<msx&&y<msy){
  230.         __asm{
  231.             xor        eax,eax
  232.             mov        al,byte ptr x
  233.             mov        ah, byte ptr y
  234.             shl        eax,1
  235.             mov        word ptr[fmap+eax],16383;
  236.         };
  237.     };
  238. };
  239. void OneObject::MakeWPreProcess(){
  240.     if(Media!=1)return;
  241.     if(NNUM==MyNation){
  242.         int x0,y0,dx,dx1;
  243.         switch(SpotType){
  244.         case 0:
  245.             if(Lx>1){
  246.             for(byte ux=0;ux<Lx;ux++)
  247.                 for(byte uy=0;uy<Ly;uy++)
  248.                     WSpot(x+ux,y+uy);
  249.             }else WSpot(x,y);
  250.             break;
  251.         case 1:
  252.             x0=x+(Lx>>1);
  253.             y0=y+(Ly>>1);
  254.             dx=SpotSize;
  255.             WSpot(x0,y0);
  256.             WSpot(x0+dx,y0);
  257.             WSpot(x0-dx,y0);
  258.             WSpot(x0,y0+dx);
  259.             WSpot(x0,y0-dx);
  260.             break;
  261.         case 2:
  262.             x0=x+(Lx>>1);
  263.             y0=y+(Ly>>1);
  264.             dx=SpotSize;
  265.             dx1=dx-(dx>>2);
  266.             WSpot(x0,y0);
  267.             WSpot(x0+dx,y0);
  268.             WSpot(x0-dx,y0);
  269.             WSpot(x0,y0+dx);
  270.             WSpot(x0,y0-dx);
  271.             WSpot(x0+dx1,y0+dx1);
  272.             WSpot(x0-dx1,y0-dx1);
  273.             WSpot(x0+dx1,y0-dx1);
  274.             WSpot(x0-dx1,y0+dx);
  275.             break;
  276.         };
  277.     };
  278.     //WMap[y][x]=1;
  279.     if(delay)delay--;
  280.     Ticks++;
  281.     if(Ticks<TicksPerChange){
  282.         Ticks++;
  283.         if(TicksPerChange!=255)return;
  284.     };
  285.     Ticks=0;
  286.         int Nsp=CurAnm->count-1;
  287.         if(CurrentSprite<Nsp&&TicksPerChange!=255){
  288.             CurrentSprite++;
  289.             //Ticks=0;
  290.             //TicksPerChange=1;
  291.             return;
  292.         };
  293.         if(Sdoxlo){
  294.             if(TicksPerChange==250){;
  295.                  Died[y][x]=0xFFFF;
  296.                  WLock[y][x]=0;
  297.                  WMap[y][x]=0;
  298.                  OneObject yy=*Group[Index];
  299.                  OneObject* OO=Group[Index];
  300.                  Group[Index]=NULL;
  301.                  OneObject OOO=*OO;
  302.                  //free(OO);
  303.                  return;
  304.             }else{
  305.                 TicksPerChange=250;
  306.                 return;
  307.             };
  308.         };
  309.         if(TicksPerChange!=255)CurrentSprite=0;
  310.         Addx=0;
  311.         Addy=0;
  312.         Removed=false;
  313.         StandTime++;
  314.         if(Life<=0){
  315.             Die();
  316.             return;
  317.         };
  318.         //if(!Important)
  319.         if(!NoSearchVictim)SearchVictim();
  320.         Order1* LO=LocalOrder;
  321.         if(!LO)PrioryLevel=0;
  322.         if(int(InLineCom)){
  323.             //MessageFlags=1;
  324.             bool    Done;
  325.             do{
  326.                 byte* p=(byte*)(int(InLineCom)+LineOffset);
  327.                 byte b=p[0];
  328.                 Done=false;
  329.  
  330.                 switch(b){
  331.                 //case 0:
  332.                 case 1:
  333.                     //Return
  334.                     FreeAsmLink();    
  335.                     //MessageFlags=MessageFlags|2;
  336.                     Done=true;
  337.                     break;
  338.                 case 3:
  339.                     //TakeNextOrder();
  340.                     {
  341.                         if(int(LocalOrder)){
  342.                             Order1* Loc1=LocalOrder->NextOrder;
  343.                             FreeOrdBlock(LocalOrder);
  344.                             LocalOrder=Loc1;
  345.                         };
  346.                         LineOffset++;
  347.                         Done=true;
  348.                     };
  349.                     break;
  350.                 case 4:
  351.                     //set coordinates
  352.                     //[04][dx][dy]
  353.                     AddWAsk(Index,x,y,p[1],p[2]);
  354.                     LineOffset+=3;
  355.                     Done=true;
  356.                     Removed=true;
  357.                     break;
  358.                 case 5:
  359.                     //set direction
  360.                     Direction=p[1];
  361.                     LineOffset+=2;
  362.                     break;
  363.                 case 6:
  364.                     LoadAnimation(p[1],p[2],p[3]);
  365.                     LineOffset+=5;
  366.                     break;
  367.                 case 7:
  368.                     //jump...
  369.                     {int pp=*(int*)(int(p)+1);
  370.                     FreeAsmBlock(InLineCom);
  371.                     LineOffset=0;
  372.                     InLineCom=(char*)pp;};
  373.                     break;
  374.                 case 8:
  375.                     //Use register to animate
  376.                     LoadCurAnm(p[1]);
  377.                     Ticks=0;
  378.                     TicksPerChange=1;
  379.                     LineOffset+=2;
  380.                     Done=true;
  381.                     break;
  382.                 default:
  383.                     assert(0);
  384.                     break;
  385.                 };
  386.             } while(!Done);
  387.             //if(int(OrderReport))OrderReport(this);
  388.             //OneObject* OBJ=Group[0];
  389.             //if(OBJ->Removed&&(OBJ->InLineCom)[OBJ->LineOffset]!=4)
  390.             //    int ggg=0;
  391.             if(LO&&LO->OrderType>127){
  392.                 //FreeAsmLink();
  393.                 LocalOrder->DoLink(this);
  394.             };
  395.         } else{ 
  396.             if(TicksPerChange!=255)LoadCurAnm(0);
  397.             Important=false;
  398.             if(int(LocalOrder)){
  399.                 LocalOrder->DoLink(this);
  400. //                if(LocalOrder->OrderType==77)
  401. //                    MoveFrom(LocalOrder->info.MoveFrom.dir);
  402.             } else    if(TicksPerChange!=255)CurrentSprite=0;
  403.         };
  404. };
  405. void MakeWPostProcess(){
  406.     HandleWAsks();
  407.     for(int i=0;i<NAsk;i++){
  408.         AskMove ASK=Ask[i];
  409.         OneObject* OBJ=Group[ASK.ReqID&8191];
  410.         if(FailLink[i]){
  411.             byte ax=ASK.x;
  412.             byte ay=ASK.y;
  413.             char oox=ax>>2;
  414.             char ooy=ay>>2;
  415.             byte adx=ASK.dx+2;
  416.             byte ady=ASK.dy+2;
  417.             byte Kind=OBJ->Kind;
  418.             OBJ->Direction=drrbw[(adx>>1)+adx+(ady>>1)];
  419.             WMap[ay][ax]=0;
  420.             OBJ->x=ax+ASK.dx;
  421.             OBJ->y=ay+ASK.dy;
  422.             char onx=OBJ->x>>2;
  423.             char ony=OBJ->y>>2;
  424.             Mops[OBJ->y][OBJ->x]=OBJ->Index;
  425.             if(Mops[ay][ax]==OBJ->Index)Mops[ay][ax]=0xFFFF;
  426.             OBJ->Addx=-ASK.dx<<5;
  427.             OBJ->Addy=-ASK.dy<<5;
  428.             OBJ->LoadCurAnm(1);
  429.             OBJ->isMoving=true;
  430.             OBJ->StandTime=0;
  431.             if(oox!=onx||ooy!=ony){
  432.                 Cell8x8* OldCell=&TCInf[OBJ->NNUM][ooy][oox];    
  433.                 Cell8x8* NewCell=&TCInf[OBJ->NNUM][ony][onx];
  434.                 OldCell->UnitsAmount[Kind]--;
  435.                 NewCell->UnitsAmount[Kind]++;
  436.             };
  437.         }else{
  438.             OBJ->StandTime++;
  439.             if(!(ASK.ReqID&0x8000)){
  440.                 byte ax=ASK.x+ASK.dx;
  441.                 byte ay=ASK.y+ASK.dy;
  442.                 int mopsa=Mops[ay][ax];
  443.                 if(mopsa!=0xFFFF){
  444.                     OneObject* OBJ2=Group[mopsa];
  445.                     if(OBJ->StandTime>1)
  446.                         OBJ2->WMoveFrom(OBJ->Direction);
  447.                 }else{;
  448.                     OBJ->FreeAsmLink();
  449.                     OBJ->LineOffset=0;
  450.                 };
  451.             };
  452.             OBJ->LoadAnimation(0,OBJ->AnmStandKind,0);
  453.             OBJ->LoadCurAnm(0);
  454.             OBJ->PathBroken=true;
  455.         };
  456.     };
  457. };
  458. byte wcirc[16];
  459. inline void FillWCirc(int x,int y){
  460.     __asm{
  461.         xor        ebx,ebx
  462.         mov        bh,byte ptr y
  463.         mov        bl,byte ptr x
  464.         add        ebx,offset WMap
  465.         mov        al,[ebx-512]
  466.         mov        wcirc[0],al
  467.         mov        al,[ebx-510]
  468.         mov        wcirc[1],al
  469.         mov        al,[ebx+2]
  470.         mov        wcirc[2],al
  471.         mov        al,[ebx+514]
  472.         mov        wcirc[3],al
  473.         mov        al,[ebx+512]
  474.         mov        wcirc[4],al
  475.         mov        al,[ebx+510]
  476.         mov        wcirc[5],al
  477.         mov        al,[ebx-2]
  478.         mov        wcirc[6],al
  479.         mov        al,[ebx-514]
  480.         mov        wcirc[7],al
  481.         mov        eax,dword ptr wcirc[0]
  482.         mov        dword ptr wcirc[8],eax
  483.         mov        eax,dword ptr wcirc[4]
  484.         mov        dword ptr wcirc[12],eax
  485.     }
  486. };
  487. //Inline- Ωε∞αφΣ√ ∩ε±≥≡εσφΦ  Γφ≤≥≡σφφΦ⌡ Ωε∞αφΣ
  488. extern int Ofst;
  489. extern char* NowBuf;
  490. inline void ChkWOfst(int size){
  491.     if(Ofst>=OneAsmSize-size-5-4){
  492.         char* NN=GetAsmBlock();
  493.         if(int(NN)){
  494.             NowBuf[Ofst]=7;
  495.             memcpy(&NowBuf[Ofst+1],&NN,4);
  496.             memcpy(&NowBuf[OneAsmSize-4],&NN,4);
  497.             NowBuf=NN;
  498.             Ofst=0;
  499.             memcpy(&NowBuf[OneAsmSize-4],&Ofst,4);
  500.         }else
  501.             NowBuf[Ofst]=0;
  502.     };
  503. };
  504. inline void cmWSetXY(byte x,byte y){
  505.     ChkWOfst(3);
  506.     NowBuf[Ofst]=4;
  507.     NowBuf[Ofst+1]=x;
  508.     NowBuf[Ofst+2]=y;
  509.     Ofst+=3;
  510. };
  511. inline void cmWSetXYDir(byte x,byte y,byte dir,byte n){
  512.     ChkWOfst(4);
  513.     NowBuf[Ofst]=18;
  514.     NowBuf[Ofst+1]=x;
  515.     NowBuf[Ofst+2]=y;
  516.     NowBuf[Ofst+3]=(dir&7)|(n<<4);
  517.     Ofst+=4;
  518. };
  519. inline void cmWSetXYDirX(byte x,byte y,char dx,char dy,byte n){
  520.     ChkWOfst(4);
  521.     byte dr=drrw[(dx+1)*3+dy+1];
  522.     NowBuf[Ofst]=18;
  523.     NowBuf[Ofst+1]=x;
  524.     NowBuf[Ofst+2]=y;
  525.     NowBuf[Ofst+3]=(dr&7)|(n<<4);
  526.     Ofst+=4;
  527. };
  528.  
  529. inline void cmWChkXY(byte x,byte y){
  530.     ChkWOfst(3);
  531.     NowBuf[Ofst]=44;
  532.     NowBuf[Ofst+1]=x;
  533.     NowBuf[Ofst+2]=y;
  534.     Ofst+=3;
  535. };
  536. inline void cmWSetDir(int dx,int dy){
  537.     if(dx==0&&dy==0)return;
  538.     byte dr=drrw[(dx+1)*3+dy+1];
  539.     ChkWOfst(2);
  540.     NowBuf[Ofst]=5;
  541.     NowBuf[Ofst+1]=dr;
  542.     Ofst+=2;
  543. };
  544. void cmWSetDirD(byte dr){
  545.     ChkWOfst(2);
  546.     NowBuf[Ofst]=5;
  547.     NowBuf[Ofst+1]=dr&7;
  548.     Ofst+=2;
  549. };
  550. inline void cmWLoadAnm(byte stype,byte dtype,word kind){
  551.     ChkWOfst(5);
  552.     NowBuf[Ofst]=6;
  553.     NowBuf[Ofst+1]=dtype;
  554.     NowBuf[Ofst+2]=stype;
  555.     NowBuf[Ofst+3]=byte(kind);
  556.     NowBuf[Ofst+4]=0;
  557.     Ofst+=5;
  558. };
  559. inline void cmWPerfAnm(byte n){
  560.     ChkWOfst(2);
  561.     NowBuf[Ofst]=8;
  562.     NowBuf[Ofst+1]=n;
  563.     Ofst+=2;
  564. };
  565. inline void cmWRet(){
  566.     NowBuf[Ofst]=1;
  567.     Ofst+=1;
  568. };
  569. inline void cmWDone(){
  570.     NowBuf[Ofst]=3;
  571.     Ofst+=1;
  572. };
  573.  
  574. void WSendToLink(OneObject* OBJ);
  575. void OneObject::WSendTo(int x2,int y2,int Prio){
  576. #define MaxP 160
  577.     if(PrioryLevel>Prio)return;
  578.     if(!cpbMoving)return;
  579.     int x1=x2&254;
  580.     int y1=y2&254;
  581.     if(WMap[y1][x1]){
  582.         //═α⌡εΣΦ∞ ßδΦµαΘ°≤■ φσταφ ≥≤■ ≥ε≈Ω≤
  583.         bool fnf=true;
  584.         for(int i=1;i<30;i++){
  585.             int z=i<<1;
  586.             for(int j=0;j<z;j++)
  587.                 if(!WMap[y1-i-i][x1-i-i+j+j]){
  588.                     x1-=i+i-j-j;
  589.                     y1-=i+i;
  590.                     goto Em_Found;
  591.                 };
  592.             for(j=0;j<z;j++)
  593.                 if(!WMap[y1-i-i+j+j][x1+i+i]){
  594.                     y1-=i+i-j-j;
  595.                     x1+=i+i;
  596.                     goto Em_Found;
  597.                 };
  598.             for(j=0;j<z;j++)
  599.                 if(!WMap[y1+i+i][x1+i+i-j-j]){
  600.                     y1+=i+i;
  601.                     x1+=i+i-j-j;
  602.                     goto Em_Found;
  603.                 };
  604.             for(j=0;j<z;j++)
  605.                 if(!WMap[y1+i+i-j][x1-i-i]){
  606.                     y1+=i+i-j-j;
  607.                     x1-=i+i;
  608.                     goto Em_Found;
  609.                 };
  610.         };
  611.     };
  612. Em_Found:
  613.     if(x==x1&&y==y1){
  614.         if(int(LocalOrder)){
  615.             if(!MemoryTime){
  616.                 if(MemoryTime)MemoryTime--;
  617.                 if(LocalOrder->OrderType==2){
  618.                     Order1* Loc1=LocalOrder->NextOrder;
  619.                     FreeOrdBlock(LocalOrder);
  620.                     LocalOrder=Loc1;
  621.                 };
  622.             };
  623.         };
  624.         if(int(InLineCom))FreeAsmLink();
  625.         //LoadAnimation(0,0,0);
  626.         //LoadCurAnm(0);
  627.         return;
  628.     };
  629.     //if(XYChanged)StandTime=0;
  630.     MemoryTime=5;
  631.     Order1* Or1=GetOrdBlock();
  632.     if(!int(Or1))return;
  633.     Or1->PrioryLevel=Prio&127;
  634.     Or1->NextOrder=NULL;
  635.     Or1->OrderType=2;
  636.     Or1->OrderTime=0;
  637.     Or1->DoLink=&WSendToLink;
  638.     Or1->info.MoveToXY.x=x1;
  639.     Or1->info.MoveToXY.y=y1;
  640.     Order1* LOR=LocalOrder;
  641.     if(int(LOR)){
  642.         //if(LOR->OrderType=2&&StandTime>5)WMap[y][x]=1;
  643.         ClearOrders();//reeOrdBlock(LocalOrder);
  644.         if(LOR->OrderType!=2)StandTime=0; 
  645.     }else StandTime=0;
  646.     //StandTime=0;
  647.     if(int(InLineCom)){
  648.         FreeAsmLink();
  649.         //LoadCurAnm(0);
  650.     };
  651.     LocalOrder=Or1;
  652.     //OrderReport=NULL;
  653.     //MessageKind=0;
  654.     //Sender=0xFFFF;
  655.     //if(Prio<128){
  656.         //PushCmd(Index);
  657.     //    return;
  658.     //};
  659.     //CreatePath(x1,y1);
  660.     PrioryLevel=Prio&127;
  661. }; 
  662. void WSendToLink(OneObject* OBJ){
  663.     byte x1=OBJ->LocalOrder->info.MoveToXY.x;
  664.     byte y1=OBJ->LocalOrder->info.MoveToXY.y;
  665.     byte Prio=OBJ->LocalOrder->PrioryLevel;
  666.     if(WMap[y1][x1])OBJ->SendTo(x1,y1,Prio);else{
  667.         byte x=OBJ->x;
  668.         byte y=OBJ->y;
  669.         if(x==x1&&y==y1){
  670.             if(int(OBJ->LocalOrder)){
  671.                 if(OBJ->MemoryTime)OBJ->MemoryTime--;
  672.                 if(!OBJ->MemoryTime){
  673.                     if(OBJ->LocalOrder->OrderType==2){
  674.                         Order1* Loc1=OBJ->LocalOrder->NextOrder;
  675.                         OBJ->FreeOrdBlock(OBJ->LocalOrder);
  676.                         OBJ->LocalOrder=Loc1;
  677.                     };
  678.                 };
  679.             };
  680.             if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  681.             //OBJ->LoadAnimation(0,0,0);
  682.             //OBJ->LoadCurAnm(0);
  683.             return;
  684.         }else{
  685.             if(int(OBJ->InLineCom)){
  686.                 OBJ->FreeAsmLink();
  687.                 //OBJ->LoadCurAnm(0);
  688.             };
  689.             OBJ->CreateWPath(x1,y1);
  690.             OBJ->MemoryTime=0;
  691.         };
  692.     };
  693. };
  694. //└≥αΩεΓα≥ⁿ εß·σΩ≥ ± ταΣαφφ√∞ ΦφΣσΩ±ε∞
  695. void WAttackObjLink(OneObject* OBJ);
  696. void OneObject::WAttackObj(word OID,int Prio){
  697.     if(Prio<PrioryLevel/*&&!Attack*/)return;
  698.     if(!Ready)return;
  699.     if(!(cpbMoving||int(Weap)))return;
  700.     ClearOrders();
  701.     OneObject* OB=Group[OID];
  702.     if(!int(OB)||OB->Sdoxlo)return;
  703.     byte x1=OB->x;
  704.     byte y1=OB->y;
  705.     int sx=x1-x;
  706.     int    sy=y1-y;
  707.     int dx=abs(sx);
  708.     int dy=abs(sy);
  709.     int dst;
  710.     if(dx>dy)dst=dx;
  711.             else dst=dy;
  712.     if((Attack&&dst>EnemyDist&&Prio<8))return;
  713.     //if(Prio<16&&dst>MaxReplyDistance)return;
  714.     Important=true;
  715.     if(Attack){
  716.         EnemyID=OID;
  717.         EnemySN=OB->Serial;
  718.         EnemyDist=dst;
  719.         //SearchSupport(OID);
  720.         return;
  721.     };
  722.     EnemyDist=dst;
  723.     //SearchSupport(OID);
  724.     if(NMask&OB->NMask)return;
  725.     Order1* Or1=GetOrdBlock();
  726.     assert(Or1);
  727.     if(!int(Or1))return;
  728.     Or1->PrioryLevel=Prio&127;
  729.     Or1->NextOrder=LocalOrder;
  730.     Or1->OrderType=3;//└≥αΩα
  731.     Or1->OrderTime=0;
  732.     Or1->DoLink=&WAttackObjLink;
  733.     Or1->info.MoveToObj.ObjIndex=OID;
  734.     EnemyID=OID;
  735.     EnemySN=OB->Serial;
  736.     Attack=true;
  737.     Order1* LOR=LocalOrder;
  738.     if(int(InLineCom))FreeAsmLink();
  739.     LocalOrder=Or1;
  740.     //OrderReport=NULL;
  741.     //MessageKind=0;
  742.     //Sender=0xFFFF;
  743.     PrioryLevel=Prio&127;
  744.     if(CrowdRef)CrowdRef->AddToAttackQueue(OID);
  745. /*
  746.  
  747.  
  748.  
  749.     if(Prio<PrioryLevel&&!Attack)return;
  750.     if(Prio>=16)StandGround=false;
  751.     if(!Ready)return;
  752.     if(!(cpbMoving||int(Weap)))return;
  753.     OneObject* OB=Group[OID];
  754.     if(!int(OB)||OB->Sdoxlo)return;
  755.     byte x1=OB->x;
  756.     byte y1=OB->y;
  757.     int sx=x1-x;
  758.     int    sy=y1-y;
  759.     int dx=abs(sx);
  760.     int dy=abs(sy);
  761.     int dst;
  762.     if(dx>dy)dst=dx;
  763.             else dst=dy;
  764.     if(dst>EnemyDist)return;
  765.     if(Prio<16&&dst>30)return;
  766.     Important=true;
  767.     if(Attack){
  768.         EnemyID=OID;
  769.         EnemySN=OB->Serial;
  770.         EnemyDist=dst;
  771.         //SearchSupport(OID);
  772.         return;
  773.     };
  774.     EnemyDist=dst;
  775.     //SearchSupport(OID);
  776.     if(NMask&OB->NMask)return;
  777.     Order1* Or1=GetOrdBlock();
  778.     if(!int(Or1))return;
  779.     Or1->PrioryLevel=Prio&127;
  780.     Or1->NextOrder=LocalOrder;
  781.     Or1->OrderType=3;//└≥αΩα
  782.     Or1->OrderTime=0;
  783.     Or1->DoLink=&WAttackObjLink;
  784.     Or1->info.MoveToObj.ObjIndex=OID;
  785.     EnemyID=OID;
  786.     EnemySN=OB->Serial;
  787.     Attack=true;
  788.     Order1* LOR=LocalOrder;
  789.     if(int(InLineCom))FreeAsmLink();
  790.     LocalOrder=Or1;
  791.     //OrderReport=NULL;
  792.     //MessageKind=0;
  793.     //Sender=0xFFFF;
  794.     PrioryLevel=Prio&127;*/
  795. };    
  796. void WAttackObjLink(OneObject* OBJ){
  797.     word OID=OBJ->EnemyID;
  798.     Order1* Or1;
  799.     if(OID>8192){
  800.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  801.         if(int(OBJ->LocalOrder)){
  802.             Or1=OBJ->LocalOrder->NextOrder;
  803.             OBJ->FreeOrdBlock(OBJ->LocalOrder);
  804.             OBJ->LocalOrder=Or1;
  805.             OBJ->Important=false;
  806.             return;
  807.         };
  808.     };
  809.     OneObject* OB=Group[OID];
  810.     OBJ->Important=true;
  811.     if(!OBJ->NeedNoHelp)OBJ->SearchSupport(OID);
  812.     if((!int(OB))||OB->Sdoxlo||OB->Serial!=OBJ->EnemySN){
  813.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  814.         if(int(OBJ->LocalOrder)){
  815.             Or1=OBJ->LocalOrder->NextOrder;
  816.             OBJ->FreeOrdBlock(OBJ->LocalOrder);
  817.             OBJ->LocalOrder=Or1;
  818.             OBJ->Important=false;
  819.             return;
  820.         };
  821.     };
  822.     byte x0=OB->x;
  823.     byte y0=OB->y;
  824.     byte olx=OB->Lx;
  825.     byte oly=OB->Ly;
  826.     byte xo=OBJ->x;
  827.     byte yo=OBJ->y;
  828.     if(xo<x0)xo=x0;else if(xo>=x0+olx)xo=x0+olx-1;
  829.     if(yo<y0)yo=y0;else if(yo>=y0+oly)yo=y0+oly-1;
  830.     int sx=xo-OBJ->x;
  831.     int    sy=yo-OBJ->y;
  832.     int dx=abs(sx);
  833.     int dy=abs(sy);
  834.     int dst;
  835.     if(dx>dy)dst=dx;
  836.             else dst=dy;
  837.     OBJ->EnemyDist=dst;
  838.     if(dst<2&&OBJ->cpbMoving&&!OBJ->delay){
  839.         OBJ->Direction=drrw[(sx+1)*3+sy+1];
  840.         OBJ->LoadAnimation(2,2,0);
  841.         OBJ->LoadCurAnm(2);
  842.         int Midm=OBJ->Ref.Visual->info.Basic.MinDamage;
  843.         int Madm=OBJ->Ref.Visual->info.Basic.MaxDamage;
  844.         int Dam=(rando()*(Madm-Midm)>>15)+Midm;
  845.         //Dam=(Dam*OBJ->xForce)>>4;
  846.         //if(OB->Life>Dam)OB->Life-=Dam;else OB->Life=0;
  847.         OB->MakeDamage(Madm,Midm,OBJ);
  848.         OBJ->isMoving=false;
  849.         OBJ->delay=OBJ->MaxDelay;
  850.     }else{ 
  851.         Visuals* VS=OBJ->Ref.Visual;
  852.         if(dst<VS->info.Basic.AttackRange&&dst>VS->DangerZone){
  853.             if(OBJ->Weap&&!OBJ->delay){
  854.                 OBJ->isMoving=false;
  855.                 OBJ->delay=OBJ->Ref.General->WepDelay;
  856.                 //OBJ->delay=OBJ->MaxDelay;
  857.                 if(OBJ->cpbMoving){
  858.                     OBJ->LoadAnimation(2,2,0);
  859.                     OBJ->LoadCurAnm(2);
  860.                     OBJ->Direction=
  861.                         CreateUniExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,OB->x,OB->y,OB->Index);
  862.                     //OBJ->Direction=
  863.                     //    AttackByWeapon(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ,OB->Index);
  864.                         //CreateExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,sx,sy,64,OBJ->NMask,OBJ);
  865.                 }else
  866.                     CreateUniExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,OB->x,OB->y,OB->Index);
  867.                     //AttackByWeapon(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ,OB->Index);
  868.                     //CreateExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,sx,sy,64,OBJ->NMask,OBJ);
  869.             };
  870.         }else
  871.         if(OBJ->cpbMoving&&!OBJ->StandGround)OBJ->CreateWPath(xo,yo);
  872.     };
  873. };
  874. extern byte xx[MaxP];
  875. extern byte yy[MaxP];
  876. void OneObject::CreateSimpleWPath(int txt1,int tyt1){
  877.     PathAsks++;
  878.     int x1=txt1&254;
  879.     int    y1=tyt1&254;
  880.     WMap[y][x]=0;
  881.     int sdx=(x1-x)>>1;
  882.     int    sdy=(y1-y)>>1;
  883.     int    Cum=0;
  884.     int Pps=0;
  885.     int sx=sdx;
  886.     int sy=sdy;
  887.     if(sx>1)sx=1;
  888.     if(sx<-1)sx=-1;
  889.     if(sy>1)sy=1;
  890.     if(sy<-1)sy=-1;
  891.     sx=sx<<1;
  892.     sy=sy<<1;
  893.     int dx=abs(sdx);
  894.     int dy=abs(sdy);
  895.     int    Mdx=dx>>1;
  896.     int    Mdy=dy>>1;
  897.     int    Mx=x;
  898.     int    My=y;
  899.     int    xx1=x;
  900.     int yy1=y;
  901.     //int rx=sx;
  902.     //int ry=sy;
  903.     //if(dx>dy)ry=0;
  904.     //if(dy>dx)rx=0;
  905.     if(!WMap[y+sy][x+sx]){
  906.         LoadAnimation(1,AnmGoKind,0);
  907.         AddAsk(Index,x,y,sx,sy);
  908.         return;
  909.     };
  910.     if(PathX)free(PathX);
  911.     if(PathY)free(PathY);
  912.     PathX=NULL;
  913.     PathY=NULL;
  914.     NIPoints=0;
  915.     CurIPoint=0;
  916.     NeedPath=false;
  917.     //±εσΣΦφ σ∞ δΦφΦσΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■ ≥ε≈ΩΦ. 
  918.     //╬∩≥Φ∞Φτα÷Φ  ≥εδⁿΩε ∩ε ±Ωε≡ε±≥Φ
  919.     __asm{
  920.         mov        ax,word ptr Mdx
  921.         mov        bx,word ptr Mdy
  922.         xor        edx,edx  //Pps
  923.         xor        ecx,ecx  //Cum
  924.         mov        si,word ptr Mx
  925.         mov        di,word ptr My
  926.         cmp        bx,ax
  927.         jae        Lp5xx
  928.         //dx>dy
  929.         mov        word ptr[xx+edx],si
  930.         mov        word ptr[yy+edx],di
  931.         inc        edx
  932.         or        ax,ax
  933.         jz        LoopsEnd
  934.         cmp        sy,0
  935.         jl        Lp3xx
  936.         cmp        sx,0
  937.         jl        Lp2begin
  938.         //dx>dy,sx>0,sy>0
  939. Lp1begin:
  940.         add        si,2    //x++
  941.         add        cx,bx
  942.         cmp        cx,word ptr Mdx
  943.         jb        Lp1_1
  944.         sub        cx,word ptr Mdx
  945.         add        di,2  //y++
  946. Lp1_1:
  947.         mov        word ptr[xx+edx],si
  948.         mov        word ptr[yy+edx],di
  949.         inc        edx
  950.         dec        ax
  951.         jnz        Lp1begin
  952.         jmp        LoopsEnd
  953. Lp2begin: //dx>dy,sx<0,sy>0
  954.         sub        si,2    //x--
  955.         add        cx,bx
  956.         cmp        cx,word ptr Mdx
  957.         jb        Lp2_1
  958.         sub        cx,word ptr Mdx
  959.         add        di,2 //y++
  960. Lp2_1:
  961.         mov        word ptr[xx+edx],si
  962.         mov        word ptr[yy+edx],di
  963.         inc        edx
  964.         dec        ax
  965.         jnz        Lp2begin
  966.         jmp        LoopsEnd
  967. Lp3xx:    //dy<0
  968.         cmp        sx,0
  969.         jl        Lp4begin
  970. Lp3begin: //dx>dy,sx>0,sy<0
  971.         add        si,2    //x++
  972.         add        cx,bx
  973.         cmp        cx,word ptr Mdx
  974.         jb        Lp3_1
  975.         sub        cx,word ptr Mdx
  976.         sub        di,2 //y--
  977. Lp3_1:
  978.         mov        word ptr[xx+edx],si
  979.         mov        word ptr[yy+edx],di
  980.         inc        edx
  981.         dec        ax
  982.         jnz        Lp3begin
  983.         jmp        LoopsEnd
  984. Lp4begin: //dx>dy,sx<0,sy<0
  985.         sub        si,2    //x--
  986.         add        cx,bx
  987.         cmp        cx,word ptr Mdx
  988.         jb        Lp4_1
  989.         sub        cx,word ptr Mdx
  990.         sub        di,2 //y--
  991. Lp4_1:
  992.         mov        word ptr[xx+edx],si
  993.         mov        word ptr[yy+edx],di
  994.         inc        edx
  995.         dec        ax
  996.         jnz        Lp4begin
  997.         jmp        LoopsEnd
  998. Lp5xx:    //dx<dy
  999.         mov        word ptr[xx+edx],si
  1000.         mov        word ptr[yy+edx],di
  1001.         inc        edx
  1002.         or        bx,bx
  1003.         jz        LoopsEnd
  1004.         cmp        sx,0
  1005.         jl        Lp7xx
  1006.         cmp        sy,0
  1007.         jl        Lp6begin
  1008. Lp5Begin:
  1009.         add        di,2    //y++
  1010.         add        cx,ax
  1011.         cmp        cx,word ptr dy
  1012.         jb        Lp5_1
  1013.         sub        cx,word ptr dy
  1014.         add        si,2    //x++
  1015. Lp5_1:
  1016.         mov        word ptr[xx+edx],si
  1017.         mov        word ptr[yy+edx],di
  1018.         inc        edx
  1019.         dec        bx
  1020.         jnz        Lp5begin
  1021.         jmp        LoopsEnd
  1022. Lp6Begin://sx>0,sy<0
  1023.         sub        di,2    //y--
  1024.         add        cx,ax
  1025.         cmp        cx,word ptr dy
  1026.         jb        Lp6_1
  1027.         sub        cx,word ptr dy
  1028.         add        si,2    //x++
  1029. Lp6_1:
  1030.         mov        word ptr[xx+edx],si
  1031.         mov        word ptr[yy+edx],di
  1032.         inc        edx
  1033.         dec        bx
  1034.         jnz        Lp6begin
  1035.         jmp        LoopsEnd
  1036. Lp7xx:    //dx<0
  1037.         cmp        sy,0
  1038.         jl        Lp8begin
  1039. Lp7Begin://dx<0,dy>0
  1040.         add        di,2    //y++
  1041.         add        cx,ax
  1042.         cmp        cx,word ptr dy
  1043.         jb        Lp7_1
  1044.         sub        cx,word ptr dy
  1045.         sub        si,2    //x--
  1046. Lp7_1:
  1047.         mov        word ptr[xx+edx],si
  1048.         mov        word ptr[yy+edx],di
  1049.         inc        edx
  1050.         dec        bx
  1051.         jnz        Lp7begin
  1052.         jmp        LoopsEnd
  1053. Lp8Begin://dx<0,dy<0
  1054.         sub        di,2    //y--
  1055.         add        cx,ax
  1056.         cmp        cx,word ptr dy
  1057.         jb        Lp8_1
  1058.         sub        cx,word ptr dy
  1059.         sub        si,2    //x--
  1060. Lp8_1:
  1061.         mov        word ptr[xx+edx],si
  1062.         mov        word ptr[yy+edx],di
  1063.         inc        edx
  1064.         dec        bx
  1065.         jnz        Lp8begin
  1066. loopsEnd:
  1067.         //shr        edx,1
  1068.         mov        Pps,edx
  1069.     };
  1070.         Pps--;
  1071. /*this is a place for new code*/
  1072.     //╬ß⌡εΣΦ∞ ±∩≡αΓα
  1073.     bool RightPrefer=true;
  1074.     int Rtx;//current point 
  1075.     int Rty;
  1076.     int Ltx;
  1077.     int Lty;
  1078.     byte Rpx[MaxP];//right path
  1079.     byte Rpy[MaxP];
  1080.     byte Lpx[MaxP];//left path
  1081.     byte Lpy[MaxP];
  1082.     int Rpp=1;//index of current point
  1083.     bool LDoing;//=true if last point reached
  1084.     bool RDoing;
  1085.  
  1086.     byte Rdirc;//currend direction
  1087.     byte Ldirc;
  1088.     int Rmaxalt;//maximum alteration,right path
  1089.     int Lmaxalt;//maximum alteration,left path
  1090.     int Rppm=0;
  1091.     int Lppm=0;
  1092.     int Rcum=0;
  1093.     int Rcum1=0;
  1094.     int Lcum=0;
  1095.     int Lcum1=0;
  1096.     byte Trr=WMap[y][x];
  1097.     WMap[y][x]=0;
  1098.     //╚Σσ∞, ∩εΩα φσ ≤∩≡σ∞±  Γ ±≥σφΩ≤
  1099.     __asm{
  1100.         xor        ebx,ebx
  1101.         mov        ecx,Pps
  1102.         xor        edx,edx //Rpp
  1103.         mov        al,[xx+edx]
  1104.         mov        [Rpx+edx],al
  1105.         mov        [Lpx+edx],al
  1106.         mov        al,[yy+edx]
  1107.         mov        [Rpy+edx],al
  1108.         mov        [Lpy+edx],al
  1109.         inc        edx
  1110. uuu_Loop:
  1111.         mov        al,[xx+edx]
  1112.         mov        [Rpx+edx],al
  1113.         mov        [Lpx+edx],al
  1114.         mov        bl,al
  1115.         mov        al,[yy+edx]
  1116.         mov        [Rpy+edx],al
  1117.         mov        [Lpy+edx],al
  1118.         mov        bh,al
  1119. //        add        bx,0101h
  1120.         cmp        byte ptr[WMap+ebx],0
  1121.         jnz        uuu_end
  1122.         inc        edx
  1123.         loop    uuu_Loop        
  1124. uuu_end:
  1125.         //shr        edx,1
  1126.         mov        Rpp,edx
  1127.     };
  1128.     Rtx=xx[Rpp-1];
  1129.     Rty=yy[Rpp-1];
  1130.     // ┼±δΦ dx>dy,≥ε φα ΩαµΣε∞ °απ≤ dx Φτ∞σφ σ≥  ±≥≡επε φα 1
  1131.     if(Rtx!=x1||Rty!=y1){
  1132.         //WLock[y][x]=false;
  1133.         Rpp-=1;
  1134.         Rtx=xx[Rpp];
  1135.         Rty=yy[Rpp];
  1136.         Ltx=xx[Rpp];
  1137.         Lty=yy[Rpp];
  1138.         int Ppi=Rpp+1;
  1139.         LDoing=true;
  1140.         RDoing=true;
  1141.         //╚∙σ∞, ∩εΩα φα⌡εΣΦ∞±  Γ ταφ ≥εΘ τεφσ
  1142.         while(WMap[yy[Ppi]][xx[Ppi]]&&Ppi<Pps)Ppi++;
  1143.         if(Ppi>Pps)LDoing=false;//╩εφ.≥ε≈Ωα φσΣε±≥ΦµΦ∞α
  1144.         int Xls=xx[Ppi-1];
  1145.         int Yls=yy[Ppi-1];
  1146.         //╙∩σ≡δΦ±ⁿ...┬√≈Φ±δ σ∞ φα∩≡αΓδσφΦσ ΣΓΦµσφΦ 
  1147.         char dtx=xx[Rpp+1]-xx[Rpp]+2;
  1148.         char dty=(yy[Rpp+1]-yy[Rpp]+2)>>1;
  1149.         Rdirc=drrw[dtx+dty+(dtx>>1)];
  1150.         Ldirc=Rdirc;
  1151.         //┬√ßΦ≡ασ∞ φα≈αδⁿφεσ φα∩≡αΓδσφΦσ-right
  1152.         FillWCirc(Rtx,Rty);
  1153.         int dirc1=(Rdirc+1)&7;
  1154.         for(int z=0;wcirc[dirc1]&&z<7;dirc1++,z++);
  1155.         Rdirc=dirc1&7;
  1156.         //-left
  1157.         dirc1=8+((Ldirc+7)&7);
  1158.         for(z=0;wcirc[dirc1]&&z<7;dirc1--,z++);
  1159.         Ldirc=dirc1&7;
  1160.         //╚Σσ∞ ∩ε ∩≡αΓε∞≤ Ω≡α■ Σε ≥σ⌡ ∩ε≡ ∩εΩα ΓφεΓⁿ φσ ∩σ≡σ±σ-
  1161.         //≈σ∞±  ± ∩≡ ∞εΘ δΦφΦσΘ, ±εσΣΦφ ■∙σΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■
  1162.         //≥ε≈ΩΦ
  1163.         Rmaxalt=0;
  1164.         Lmaxalt=0;
  1165.         while(Rpp<MaxP-8&&(LDoing&&RDoing)){
  1166.             //∩√≥ασ∞±  ∩εΓσ≡φ≤≥ⁿ φα∩≡αΓε
  1167.             FillWCirc(Rtx,Rty);
  1168.             int dirc1=(Rdirc+7)&7;
  1169.             for(int z=0;z<6&&wcirc[dirc1];dirc1++,z++);
  1170.             Rdirc=dirc1&7;
  1171.             Rpp++;
  1172.             int Tdx=idrxw[Rdirc];
  1173.             int Tdy=idryw[Rdirc];
  1174.             Rcum-=sdy*Tdx;
  1175.             Rcum+=sdx*Tdy;
  1176.             Rtx+=Tdx+Tdx;
  1177.             Rty+=Tdy+Tdy;
  1178.             Rpx[Rpp]=Rtx;Rpy[Rpp]=Rty;
  1179.             //the same, but left
  1180.             FillWCirc(Ltx,Lty);
  1181.             dirc1=8+((Ldirc+1)&7);
  1182.             for(z=0;z<6&&wcirc[dirc1];dirc1--,z++);
  1183.             Ldirc=dirc1&7;
  1184.             Tdx=idrxw[Ldirc];
  1185.             Tdy=idryw[Ldirc];
  1186.             Lcum+=sdy*Tdx;
  1187.             Lcum-=sdx*Tdy;
  1188.             Ltx+=Tdx+Tdx;
  1189.             Lty+=Tdy+Tdy;
  1190.             Lpx[Rpp]=Ltx;Lpy[Rpp]=Lty;
  1191.             //┬√≈Φ±δ σ∞ τφα≈σφΦσ y φα ∩≡ ∞εΘ δΦφΦΦ, ±εε≥Γ. 
  1192.             //Σαφφε∞≤ x
  1193.             if(Rcum<=0&&Rcum1>=0){
  1194.                 if(dx>dy){
  1195.                     if(sx>0){
  1196.                         if(Rtx>=Xls)RDoing=false;
  1197.                     }else if(Rtx<=Xls)RDoing=false;
  1198.                 }else{
  1199.                     if(sy>0){
  1200.                         if(Rty>=Yls)RDoing=false;
  1201.                     }else if(Rty<=Yls)RDoing=false;
  1202.                 };
  1203.                 if(!RDoing)RightPrefer=true;
  1204.             };
  1205.             //┬√≈Φ±δ σ∞ ∞αΩ±Φ∞αδⁿφεσ ε≥ΩδεφσφΦσ ε≥ ∩≡ ∞εΘ δΦφΦΦ
  1206.             if(Rcum>=Rmaxalt){
  1207.                 Rmaxalt=Rcum;
  1208.                 Rppm=Rpp;
  1209.             };
  1210.             Rcum1=Rcum;
  1211.             //the same for left
  1212.             if(Lcum<=0&&Lcum1>=0){
  1213.                 if(dx>dy){
  1214.                     if(sx>0){
  1215.                         if(Ltx>=Xls)LDoing=false;
  1216.                     }else if(Ltx<=Xls)LDoing=false;
  1217.                 }else{
  1218.                     if(sy>0){
  1219.                         if(Lty>=Yls)LDoing=false;
  1220.                     }else if(Lty<=Yls)LDoing=false;
  1221.                 };
  1222.                 if(!LDoing)RightPrefer=false;
  1223.             };
  1224.             //┬√≈Φ±δ σ∞ ∞αΩ±Φ∞αδⁿφεσ ε≥ΩδεφσφΦσ ε≥ ∩≡ ∞εΘ δΦφΦΦ
  1225.             if(Lcum>=Lmaxalt){
  1226.                 Lmaxalt=Lcum;
  1227.                 Lppm=Rpp;
  1228.             };
  1229.             Lcum1=Lcum;
  1230.         };
  1231.         //LLock[y][x]=true;
  1232.         if(Rpp<MaxP-9){
  1233.             if(RightPrefer){
  1234.                 if(Rppm+1<Rpp)Rppm+=1;else Rppm=Rpp;
  1235.                 memcpy(xx,Rpx,(Rppm+1));
  1236.                 memcpy(yy,Rpy,(Rppm+1));
  1237.                 Pps=Rppm;
  1238.             }else{
  1239.                 if(Lppm+1<Rpp)Lppm+=1;else Lppm=Rpp;
  1240.                 memcpy(xx,Lpx,(Lppm+1));
  1241.                 memcpy(yy,Lpy,(Lppm+1));
  1242.                 Pps=Lppm;
  1243.             };
  1244.         }else return;
  1245.         //╬∩≥Φ∞Φτα÷Φ  ∩≤≥Φ
  1246.         //Pps=Optima1(Pps);
  1247.     };
  1248.     //WMap[y][x]=Trr;
  1249.     NowBuf=GetAsmBlock();
  1250.     Ofst=0;
  1251.     memcpy(&NowBuf[OneAsmSize-4],&Ofst,4);
  1252.     InLineCom=NowBuf;
  1253.     LineOffset=0;
  1254.     cmWLoadAnm(AnmGoKind,1,0);
  1255.     //cmLoadAnm(1,1,0);
  1256.     cmWLoadAnm(AnmStandKind,0,0);
  1257.     for(int i=1;i<=Pps;i++){
  1258.         //byte (*XXX)[64];
  1259.         //memcpy(&XXX,&NowBuf,4);
  1260.         //if(i==1)cmPerfAnm(0);
  1261.         cmWSetXY((xx[i]-xx[i-1])>>1,(yy[i]-yy[i-1])>>1);
  1262.     };
  1263.     cmWLoadAnm(AnmStandKind,0,0);
  1264.     cmWPerfAnm(0);
  1265.     //cmDone();
  1266.     cmWRet();
  1267. };
  1268. int GetRAngle(int dx,int dy,int Angle);
  1269. int GetLAngle(int dx,int dy,int Angle);
  1270. void OneObject::CreatePreWPath(int txt1,int tyt1){
  1271.     PathAsks++;
  1272.     int x1=txt1&254;
  1273.     int    y1=tyt1&254;
  1274.     WMap[y][x]=0;
  1275.     int sdx=(x1-x)>>1;
  1276.     int    sdy=(y1-y)>>1;
  1277.     int    Cum=0;
  1278.     int Pps=0;
  1279.     int sx=sdx;
  1280.     int sy=sdy;
  1281.     if(sx>1)sx=1;
  1282.     if(sx<-1)sx=-1;
  1283.     if(sy>1)sy=1;
  1284.     if(sy<-1)sy=-1;
  1285.     sx=sx<<1;
  1286.     sy=sy<<1;
  1287.     int dx=abs(sdx);
  1288.     int dy=abs(sdy);
  1289.     int    Mdx=dx;//>>1;
  1290.     int    Mdy=dy;//>>1;
  1291.     int    Mx=x;
  1292.     int    My=y;
  1293.     int    xx1=x;
  1294.     int yy1=y;
  1295.     int rx=sx;
  1296.     int ry=sy;
  1297.     //if(dx>dy)ry=0;
  1298.     //if(dy>dx)rx=0;
  1299.     int Angle0=GetLAngle(x1-x,y1-y,0);
  1300.     int Angle;
  1301.     int ddx,ddy;
  1302.     int Lvp=0;
  1303.     int Rvp=0;
  1304.     bool LvpLast=false;
  1305.     bool RvpLast=false;
  1306.     if(PathX)free(PathX);
  1307.     if(PathY)free(PathY);
  1308.     PathX=NULL;
  1309.     PathY=NULL;
  1310.     NIPoints=0;
  1311.     CurIPoint=0;
  1312.     NeedPath=false;
  1313.     //±εσΣΦφ σ∞ δΦφΦσΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■ ≥ε≈ΩΦ. 
  1314.     //╬∩≥Φ∞Φτα÷Φ  ≥εδⁿΩε ∩ε ±Ωε≡ε±≥Φ
  1315.     __asm{
  1316.         mov        ax,word ptr Mdx
  1317.         mov        bx,word ptr Mdy
  1318.         xor        edx,edx  //Pps
  1319.         xor        ecx,ecx  //Cum
  1320.         mov        si,word ptr Mx
  1321.         mov        di,word ptr My
  1322.         cmp        bx,ax
  1323.         jae        Lp5xx
  1324.         //dx>dy
  1325.         mov        word ptr[xx+edx],si
  1326.         mov        word ptr[yy+edx],di
  1327.         inc        edx
  1328.         or        ax,ax
  1329.         jz        LoopsEnd
  1330.         cmp        sy,0
  1331.         jl        Lp3xx
  1332.         cmp        sx,0
  1333.         jl        Lp2begin
  1334.         //dx>dy,sx>0,sy>0
  1335. Lp1begin:
  1336.         add        si,2    //x++
  1337.         add        cx,bx
  1338.         cmp        cx,word ptr Mdx
  1339.         jb        Lp1_1
  1340.         sub        cx,word ptr Mdx
  1341.         add        di,2  //y++
  1342. Lp1_1:
  1343.         mov        word ptr[xx+edx],si
  1344.         mov        word ptr[yy+edx],di
  1345.         inc        edx
  1346.         dec        ax
  1347.         jnz        Lp1begin
  1348.         jmp        LoopsEnd
  1349. Lp2begin: //dx>dy,sx<0,sy>0
  1350.         sub        si,2    //x--
  1351.         add        cx,bx
  1352.         cmp        cx,word ptr Mdx
  1353.         jb        Lp2_1
  1354.         sub        cx,word ptr Mdx
  1355.         add        di,2 //y++
  1356. Lp2_1:
  1357.         mov        word ptr[xx+edx],si
  1358.         mov        word ptr[yy+edx],di
  1359.         inc        edx
  1360.         dec        ax
  1361.         jnz        Lp2begin
  1362.         jmp        LoopsEnd
  1363. Lp3xx:    //dy<0
  1364.         cmp        sx,0
  1365.         jl        Lp4begin
  1366. Lp3begin: //dx>dy,sx>0,sy<0
  1367.         add        si,2    //x++
  1368.         add        cx,bx
  1369.         cmp        cx,word ptr Mdx
  1370.         jb        Lp3_1
  1371.         sub        cx,word ptr Mdx
  1372.         sub        di,2 //y--
  1373. Lp3_1:
  1374.         mov        word ptr[xx+edx],si
  1375.         mov        word ptr[yy+edx],di
  1376.         inc        edx
  1377.         dec        ax
  1378.         jnz        Lp3begin
  1379.         jmp        LoopsEnd
  1380. Lp4begin: //dx>dy,sx<0,sy<0
  1381.         sub        si,2    //x--
  1382.         add        cx,bx
  1383.         cmp        cx,word ptr Mdx
  1384.         jb        Lp4_1
  1385.         sub        cx,word ptr Mdx
  1386.         sub        di,2 //y--
  1387. Lp4_1:
  1388.         mov        word ptr[xx+edx],si
  1389.         mov        word ptr[yy+edx],di
  1390.         inc        edx
  1391.         dec        ax
  1392.         jnz        Lp4begin
  1393.         jmp        LoopsEnd
  1394. Lp5xx:    //dx<dy
  1395.         mov        word ptr[xx+edx],si
  1396.         mov        word ptr[yy+edx],di
  1397.         inc        edx
  1398.         or        bx,bx
  1399.         jz        LoopsEnd
  1400.         cmp        sx,0
  1401.         jl        Lp7xx
  1402.         cmp        sy,0
  1403.         jl        Lp6begin
  1404. Lp5Begin:
  1405.         add        di,2    //y++
  1406.         add        cx,ax
  1407.         cmp        cx,word ptr dy
  1408.         jb        Lp5_1
  1409.         sub        cx,word ptr dy
  1410.         add        si,2    //x++
  1411. Lp5_1:
  1412.         mov        word ptr[xx+edx],si
  1413.         mov        word ptr[yy+edx],di
  1414.         inc        edx
  1415.         dec        bx
  1416.         jnz        Lp5begin
  1417.         jmp        LoopsEnd
  1418. Lp6Begin://sx>0,sy<0
  1419.         sub        di,2    //y--
  1420.         add        cx,ax
  1421.         cmp        cx,word ptr dy
  1422.         jb        Lp6_1
  1423.         sub        cx,word ptr dy
  1424.         add        si,2    //x++
  1425. Lp6_1:
  1426.         mov        word ptr[xx+edx],si
  1427.         mov        word ptr[yy+edx],di
  1428.         inc        edx
  1429.         dec        bx
  1430.         jnz        Lp6begin
  1431.         jmp        LoopsEnd
  1432. Lp7xx:    //dx<0
  1433.         cmp        sy,0
  1434.         jl        Lp8begin
  1435. Lp7Begin://dx<0,dy>0
  1436.         add        di,2    //y++
  1437.         add        cx,ax
  1438.         cmp        cx,word ptr dy
  1439.         jb        Lp7_1
  1440.         sub        cx,word ptr dy
  1441.         sub        si,2    //x--
  1442. Lp7_1:
  1443.         mov        word ptr[xx+edx],si
  1444.         mov        word ptr[yy+edx],di
  1445.         inc        edx
  1446.         dec        bx
  1447.         jnz        Lp7begin
  1448.         jmp        LoopsEnd
  1449. Lp8Begin://dx<0,dy<0
  1450.         sub        di,2    //y--
  1451.         add        cx,ax
  1452.         cmp        cx,word ptr dy
  1453.         jb        Lp8_1
  1454.         sub        cx,word ptr dy
  1455.         sub        si,2    //x--
  1456. Lp8_1:
  1457.         mov        word ptr[xx+edx],si
  1458.         mov        word ptr[yy+edx],di
  1459.         inc        edx
  1460.         dec        bx
  1461.         jnz        Lp8begin
  1462. loopsEnd:
  1463.         //shr        edx,1
  1464.         mov        Pps,edx
  1465.     };
  1466.         Pps--;
  1467. /*this is a place for new code*/
  1468.     //╬ß⌡εΣΦ∞ ±∩≡αΓα
  1469.     bool RightPrefer=true;
  1470.     int Rtx;//current point 
  1471.     int Rty;
  1472.     int Ltx;
  1473.     int Lty;
  1474.     byte Rpx[MaxP];//right path
  1475.     byte Rpy[MaxP];
  1476.     byte Lpx[MaxP];//left path
  1477.     byte Lpy[MaxP];
  1478.     int Rpp=1;//index of current point
  1479.     bool LDoing;//=true if last point reached
  1480.     bool RDoing;
  1481.  
  1482.     byte Rdirc;//currend direction
  1483.     byte Ldirc;
  1484.     int Rmaxalt;//maximum alteration,right path
  1485.     int Lmaxalt;//maximum alteration,left path
  1486.     int Rppm=0;
  1487.     int Lppm=0;
  1488.     int Rcum=0;
  1489.     int Rcum1=0;
  1490.     int Lcum=0;
  1491.     int Lcum1=0;
  1492.     byte Trr=WMap[y][x];
  1493.     WMap[y][x]=0;
  1494.     //╚Σσ∞, ∩εΩα φσ ≤∩≡σ∞±  Γ ±≥σφΩ≤
  1495.     __asm{
  1496.         xor        ebx,ebx
  1497.         mov        ecx,Pps
  1498.         xor        edx,edx //Rpp
  1499.         mov        al,[xx+edx]
  1500.         mov        [Rpx+edx],al
  1501.         mov        [Lpx+edx],al
  1502.         mov        al,[yy+edx]
  1503.         mov        [Rpy+edx],al
  1504.         mov        [Lpy+edx],al
  1505.         inc        edx
  1506. uuu_Loop:
  1507.         mov        al,[xx+edx]
  1508.         mov        [Rpx+edx],al
  1509.         mov        [Lpx+edx],al
  1510.         mov        bl,al
  1511.         mov        al,[yy+edx]
  1512.         mov        [Rpy+edx],al
  1513.         mov        [Lpy+edx],al
  1514.         mov        bh,al
  1515. //        add        bx,0101h
  1516.         cmp        byte ptr[WMap+ebx],0
  1517.         jnz        uuu_end
  1518.         inc        edx
  1519.         loop    uuu_Loop        
  1520. uuu_end:
  1521.         //shr        edx,1
  1522.         mov        Rpp,edx
  1523.     };
  1524.     Rtx=xx[Rpp-1];
  1525.     Rty=yy[Rpp-1];
  1526.     // ┼±δΦ dx>dy,≥ε φα ΩαµΣε∞ °απ≤ dx Φτ∞σφ σ≥  ±≥≡επε φα 1
  1527.     if(Rtx!=x1||Rty!=y1){
  1528.         //WLock[y][x]=false;
  1529.         Rpp-=1;
  1530.         Rtx=xx[Rpp];
  1531.         Rty=yy[Rpp];
  1532.         Ltx=xx[Rpp];
  1533.         Lty=yy[Rpp];
  1534.         int Ppi=Rpp+1;
  1535.         LDoing=true;
  1536.         RDoing=true;
  1537.         //╚∙σ∞, ∩εΩα φα⌡εΣΦ∞±  Γ ταφ ≥εΘ τεφσ
  1538.         while(WMap[yy[Ppi]][xx[Ppi]]&&Ppi<Pps)Ppi++;
  1539.         if(Ppi>Pps)LDoing=false;//╩εφ.≥ε≈Ωα φσΣε±≥ΦµΦ∞α
  1540.         int Xls=xx[Ppi-1];
  1541.         int Yls=yy[Ppi-1];
  1542.         //╙∩σ≡δΦ±ⁿ...┬√≈Φ±δ σ∞ φα∩≡αΓδσφΦσ ΣΓΦµσφΦ 
  1543.         char dtx=xx[Rpp+1]-xx[Rpp]+2;
  1544.         char dty=(yy[Rpp+1]-yy[Rpp]+2)>>1;
  1545.         Rdirc=drrw[dtx+dty+(dtx>>1)];
  1546.         Ldirc=Rdirc;
  1547.         //┬√ßΦ≡ασ∞ φα≈αδⁿφεσ φα∩≡αΓδσφΦσ-right
  1548.         FillWCirc(Rtx,Rty);
  1549.         int dirc1=(Rdirc+1)&7;
  1550.         for(int z=0;wcirc[dirc1]&&z<7;dirc1++,z++);
  1551.         Rdirc=dirc1&7;
  1552.         //-left
  1553.         dirc1=8+((Ldirc+7)&7);
  1554.         for(z=0;wcirc[dirc1]&&z<7;dirc1--,z++);
  1555.         Ldirc=dirc1&7;
  1556.         //╚Σσ∞ ∩ε ∩≡αΓε∞≤ Ω≡α■ Σε ≥σ⌡ ∩ε≡ ∩εΩα ΓφεΓⁿ φσ ∩σ≡σ±σ-
  1557.         //≈σ∞±  ± ∩≡ ∞εΘ δΦφΦσΘ, ±εσΣΦφ ■∙σΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■
  1558.         //≥ε≈ΩΦ
  1559.         Rmaxalt=0;
  1560.         Lmaxalt=0;
  1561.         while(Rpp<MaxP-8&&(LDoing&&RDoing)){
  1562.             //∩√≥ασ∞±  ∩εΓσ≡φ≤≥ⁿ φα∩≡αΓε
  1563.             FillWCirc(Rtx,Rty);
  1564.             int dirc1=(Rdirc+7)&7;
  1565.             for(int z=0;z<6&&wcirc[dirc1];dirc1++,z++);
  1566.             Rdirc=dirc1&7;
  1567.             Rpp++;
  1568.             int Tdx=idrxw[Rdirc];
  1569.             int Tdy=idryw[Rdirc];
  1570.             Rcum-=sdy*Tdx;
  1571.             Rcum+=sdx*Tdy;
  1572.             Rtx+=Tdx+Tdx;
  1573.             Rty+=Tdy+Tdy;
  1574.             Rpx[Rpp]=Rtx;Rpy[Rpp]=Rty;
  1575.             Angle=GetLAngle(Rtx-x,Rty-y,Angle0);
  1576.             if(Angle>Rmaxalt){
  1577.                 Rmaxalt=Angle;
  1578.                 Rppm=Rpp;
  1579.             };
  1580.             //∩≡εΓσ≡ σ∞ ≤±δεΓΦσ ∩≡ ∞εΘ ΓΦΣΦ∞ε±≥Φ
  1581.             ddx=x1-Rtx;
  1582.             ddy=y1-Rty;
  1583.             if(ddx>1)ddx=1;
  1584.             if(ddx<-1)ddx=-1;
  1585.             if(ddy>1)ddy=1;
  1586.             if(ddy<-1)ddy=-1;
  1587.             ddx=ddx<<1;
  1588.             ddy=ddy<<1;
  1589.             if(!WMap[Rty+ddy][Rtx+ddx]){
  1590.                 if(!RvpLast){
  1591.                     Rvp=Rpp;
  1592.                     RvpLast=true;
  1593.                 };
  1594.             }else RvpLast=false;
  1595.             //the same, but left
  1596.             FillWCirc(Ltx,Lty);
  1597.             dirc1=8+((Ldirc+1)&7);
  1598.             for(z=0;z<6&&wcirc[dirc1];dirc1--,z++);
  1599.             Ldirc=dirc1&7;
  1600.             Tdx=idrxw[Ldirc];
  1601.             Tdy=idryw[Ldirc];
  1602.             Lcum+=sdy*Tdx;
  1603.             Lcum-=sdx*Tdy;
  1604.             Ltx+=Tdx+Tdx;
  1605.             Lty+=Tdy+Tdy;
  1606.             Lpx[Rpp]=Ltx;Lpy[Rpp]=Lty;
  1607.             Angle=GetRAngle(Ltx-x,Lty-y,Angle0);
  1608.             if(Angle>Lmaxalt){
  1609.                 Lmaxalt=Angle;
  1610.                 Lppm=Rpp;
  1611.             };
  1612.             //∩≡εΓσ≡ σ∞ ≤±δεΓΦσ ∩≡ ∞εΘ ΓΦΣΦ∞ε±≥Φ
  1613.             ddx=x1-Ltx;
  1614.             ddy=y1-Lty;
  1615.             if(ddx>1)ddx=1;
  1616.             if(ddx<-1)ddx=-1;
  1617.             if(ddy>1)ddy=1;
  1618.             if(ddy<-1)ddy=-1;
  1619.             ddx=ddx<<1;
  1620.             ddy=ddy<<1;
  1621.             if(!WMap[Lty+ddy][Ltx+ddx]){
  1622.                 if(!LvpLast){
  1623.                     Lvp=Rpp;
  1624.                     LvpLast=true;
  1625.                 };
  1626.             }else LvpLast=false;
  1627.             //┬√≈Φ±δ σ∞ τφα≈σφΦσ y φα ∩≡ ∞εΘ δΦφΦΦ, ±εε≥Γ. 
  1628.             //Σαφφε∞≤ x
  1629.             if(Rcum<=0&&Rcum1>=0){
  1630.                 if(dx>dy){
  1631.                     if(sx>0){
  1632.                         if(Rtx>=Xls)RDoing=false;
  1633.                     }else if(Rtx<=Xls)RDoing=false;
  1634.                 }else{
  1635.                     if(sy>0){
  1636.                         if(Rty>=Yls)RDoing=false;
  1637.                     }else if(Rty<=Yls)RDoing=false;
  1638.                 };
  1639.                 if(!RDoing)RightPrefer=true;
  1640.             };
  1641.             Rcum1=Rcum;
  1642.             //the same for left
  1643.             if(Lcum<=0&&Lcum1>=0){
  1644.                 if(dx>dy){
  1645.                     if(sx>0){
  1646.                         if(Ltx>=Xls)LDoing=false;
  1647.                     }else if(Ltx<=Xls)LDoing=false;
  1648.                 }else{
  1649.                     if(sy>0){
  1650.                         if(Lty>=Yls)LDoing=false;
  1651.                     }else if(Lty<=Yls)LDoing=false;
  1652.                 };
  1653.                 if(!LDoing)RightPrefer=false;
  1654.             };
  1655.             Lcum1=Lcum;
  1656.         };
  1657.         //LLock[y][x]=true;
  1658.         if(Rpp<MaxP-9){
  1659.             if(RightPrefer){
  1660.                 //if(Rppm+1<Rpp)Rppm+=1;else Rppm=Rpp;
  1661.                 //memcpy(xx,Rpx,(Rppm+1));
  1662.                 //memcpy(yy,Rpy,(Rppm+1));
  1663.                 Pps=Rppm;
  1664.             }else{
  1665.                 //if(Lppm+1<Rpp)Lppm+=1;else Lppm=Rpp;
  1666.                 //memcpy(xx,Lpx,(Lppm+1));
  1667.                 //memcpy(yy,Lpy,(Lppm+1));
  1668.                 Pps=Lppm;
  1669.                 Rvp=Lvp;
  1670.                 
  1671.             };
  1672.             if(Rvp<Pps)Rvp=Pps;
  1673.             NIPoints=Rvp-Pps+1;
  1674.             int maxp=NIPoints;
  1675.             CurIPoint=0;
  1676.             if(NIPoints>2){
  1677.                 NIPoints=2+((NIPoints-2)>>1);
  1678.             };
  1679.             PathX=new byte [NIPoints];
  1680.             PathY=new byte [NIPoints];
  1681.             if(RightPrefer){
  1682.                 if(maxp<=2){
  1683.                     memcpy(PathX,&Rpx[Pps],NIPoints);
  1684.                     memcpy(PathY,&Rpy[Pps],NIPoints);
  1685.                 }else{
  1686.                     int np=((maxp-2)>>1)+1;
  1687.                     for(int nn=0;nn<np;nn++){
  1688.                         PathX[nn]=Rpx[Pps+(nn<<1)];
  1689.                         PathY[nn]=Rpy[Pps+(nn<<1)];
  1690.                     };
  1691.                     PathX[nn]=Rpx[Pps+maxp-1];
  1692.                     PathY[nn]=Rpy[Pps+maxp-1];
  1693.                 };
  1694.             }else{
  1695.                 if(maxp<=2){
  1696.                     memcpy(PathX,&Lpx[Pps],NIPoints);
  1697.                     memcpy(PathY,&Lpy[Pps],NIPoints);
  1698.                 }else{
  1699.                     int np=((maxp-2)>>1)+1;
  1700.                     for(int nn=0;nn<np;nn++){
  1701.                         PathX[nn]=Lpx[Pps+(nn<<1)];
  1702.                         PathY[nn]=Lpy[Pps+(nn<<1)];
  1703.                     };
  1704.                     PathX[nn]=Lpx[Pps+maxp-1];
  1705.                     PathY[nn]=Lpy[Pps+maxp-1];
  1706.                 };
  1707.             };
  1708.             NeedPath=true;
  1709.         }else return;
  1710.     };
  1711. };
  1712. void OneObject::CreateWPath(int x1,int y1){
  1713.     if(CPdestX==x1&&CPdestY==y1){
  1714.         if(PathX){
  1715.             if(CurIPoint<NIPoints){
  1716.                 byte cx=PathX[CurIPoint];
  1717.                 byte cy=PathY[CurIPoint];
  1718.                 int dis=DistTo(cx,cy);
  1719.                 if(dis<2)CurIPoint++;
  1720.                 //else if(dis<4&&ChkStright(x,y,cx,cy))CurIPoint++;
  1721.                 if(CurIPoint<NIPoints){
  1722.                     CreateSimpleWPath(PathX[CurIPoint],PathY[CurIPoint]);
  1723.                 }else{
  1724.                     int xx1=x;
  1725.                     int yy1=y;
  1726.                     x=cx;
  1727.                     y=cy;
  1728.                     CreatePreWPath(x1,y1);
  1729.                     x=xx1;
  1730.                     y=yy1;
  1731.                 };
  1732.             };
  1733.         }else CreateSimpleWPath(x1,y1);
  1734.     }else{
  1735.         CreatePreWPath(x1,y1);
  1736.     };
  1737.     CPdestX=x1;
  1738.     CPdestY=y1;
  1739. };
  1740. extern word LastObject;
  1741. bool Nation::CreateOnWater(int xp,int yp,int n){
  1742.     int x=xp&254;
  1743.     int y=yp&254;
  1744.     if( Mops[y][x]!=0xFFFF||WLock[y][x])return false;
  1745.     for(int i=0;i<MaxObj&&int(Group[i]);i++);
  1746.     if(i>=MaxObj)return false;
  1747.     if(n>=NMon) return false;
  1748.     if(i>=MAXOBJECT)MAXOBJECT=i+1;
  1749.     Group[i]=OBJECTS+i;
  1750.     LastObject=i;
  1751.     OneObject* G=Group[i];
  1752.     GeneralObject* GO=Mon[n];
  1753.     AddOrderEffect(x,y,GO->BornSound);
  1754.     Cell8x8* CELL=&TCInf[NNUM][y>>2][x>>2];
  1755.     CELL->UnitsAmount[GO->Kind]++;
  1756.     G->DefaultSettings(GO);
  1757.     G->Kind=GO->Kind;
  1758.     G->Media=1;
  1759.     G->Teleport=false;
  1760.     G->capTeleport=GO->Teleport;
  1761.     G->OnWater=true;
  1762.     G->CrowdRef=NULL;
  1763.     G->VisRadius=GO->VisRadius;
  1764.     G->VisSpots=GO->VisSpots;
  1765.     G->SpotType=GO->SpotType;
  1766.     G->SpotSize=GO->SpotSize;
  1767.     G->DangerZone=GO->DangerZone;
  1768.     G->NoSearchVictim=GO->NoSearchVictim;
  1769.     G->NoAnswer=GO->NoAnswer;
  1770.     G->NeedNoHelp=GO->NeedNoHelp;
  1771.     G->Nat=this;
  1772.     G->Ready=true;
  1773.     G->wepX=GO->wepX;
  1774.     G->wepY=GO->wepY;
  1775.     G->MaxDelay=GO->delay;
  1776.     G->delay=0;
  1777.     G->NearBase=0xFFFF;
  1778.     G->capBase=GO->cpbBase;
  1779.     G->RStage=0;
  1780.     G->RType=0;
  1781.     G->RAmount=0;
  1782.     G->NNUM=NNUM;
  1783.     G->NIndex=n;
  1784.     G->AnmStandKind=0;
  1785.     G->AnmGoKind=1;
  1786.     G->capBuild=GO->cpbBuild;
  1787.     G->GroupIndex=NULL;
  1788.     G->cpbMoving=GO->cpbMoving;
  1789.     if(!GO->SizeX)GO->SizeX=1;
  1790.     if(!GO->SizeY)GO->SizeY=1;
  1791.     G->Lx=GO->SizeX;
  1792.     G->Ly=GO->SizeY;
  1793.     G->TempFlag=false;
  1794.     G->Mobilised=false;
  1795.     G->Wars=NULL;
  1796.     G->Index=i;
  1797.     Mops[y][x]=i;
  1798.     Visuals* m;
  1799.     m=(Visuals*)Mon[n];
  1800.     G->Selected=false;
  1801.     G->Borg=false;
  1802.     G->Life=m->info.Basic.MaxLife;
  1803.     G->MaxLife=m->info.Basic.MaxLife;
  1804.     G->Ref.Visual=m;
  1805.     G->x=x;
  1806.     G->y=y;
  1807.     G->Push=false;
  1808.     WLock[y][x]=true;
  1809.     //WMap[y][x]=1;
  1810.     G->Direction=rando() & 7;
  1811.     memset(&(G->ARegs),0,sizeof G->ARegs);
  1812.     G->LoadAnimation(0,0,0);
  1813.     G->LoadCurAnm(0);
  1814.     G->LocalOrder=NULL;
  1815.     //G->OrderReport=NULL;
  1816.     //G->MessageFlags=0;
  1817.     G->PrioryLevel=0;
  1818.     //G->MessageKind=0;
  1819.     G->InLineCom=NULL;
  1820.     G->LineOffset=0;
  1821.     G->Ticks=0;
  1822.     G->TicksPerChange=10;
  1823.     G->Wait=0;
  1824.     G->Addx=0;
  1825.     G->Addy=0;
  1826.     G->Npush=0;
  1827.     G->StandTime=100;
  1828.     G->Sdoxlo=false;
  1829.     G->Weap=Mon[n]->Weap;
  1830.     G->NMask=NMask;
  1831.     G->Important=false;
  1832.     G->EnemyDist=5000;
  1833.     G->Attack=false;
  1834.     G->EnemyID=0xFFFF;
  1835.     G->Egoist=false;
  1836.     G->NInside=0;
  1837.     if(GO->Transport){
  1838.         G->Transport=true;
  1839.  
  1840.     };
  1841.     NGidot++;
  1842.     return true;
  1843. };
  1844. inline void WReMemCirc(byte x,byte y){
  1845.     __asm{
  1846.         xor        ebx,ebx
  1847.         mov        bh,byte ptr y
  1848.         mov        bl,byte ptr x
  1849.         add        ebx,offset WMap
  1850.         mov        al,wcirc[0]
  1851.         mov        [ebx-512],al
  1852.         mov        al,wcirc[1]
  1853.         mov        [ebx-510],al
  1854.         mov        al,wcirc[2]
  1855.         mov        [ebx+2],al
  1856.         mov        al,wcirc[3]
  1857.         mov        [ebx+514],al
  1858.         mov        al,wcirc[4]
  1859.         mov        [ebx+512],al
  1860.         mov        al,wcirc[5]
  1861.         mov        [ebx+510],al
  1862.         mov        al,wcirc[6]
  1863.         mov        [ebx-2],al
  1864.         mov        al,wcirc[7]
  1865.         mov        [ebx-514],al
  1866.         xor        ebx,ebx
  1867.         mov        bh,byte ptr y
  1868.         mov        bl,byte ptr x
  1869.         add        ebx,offset WLock
  1870.         mov        al,wcirc[8]
  1871.         mov        [ebx-512],al
  1872.         mov        al,wcirc[9]
  1873.         mov        [ebx-510],al
  1874.         mov        al,wcirc[10]
  1875.         mov        [ebx+2],al
  1876.         mov        al,wcirc[11]
  1877.         mov        [ebx+514],al
  1878.         mov        al,wcirc[12]
  1879.         mov        [ebx+512],al
  1880.         mov        al,wcirc[13]
  1881.         mov        [ebx+510],al
  1882.         mov        al,wcirc[14]
  1883.         mov        [ebx-2],al
  1884.         mov        al,wcirc[15]
  1885.         mov        [ebx-514],al
  1886.     }
  1887. };
  1888. inline void WMemCirc(byte x,byte y){
  1889.     __asm{
  1890.         xor        ebx,ebx
  1891.         mov        bh,byte ptr y
  1892.         mov        bl,byte ptr x
  1893.         add        ebx,offset WMap
  1894.         mov        al,[ebx-512]
  1895.         mov        wcirc[0],al
  1896.         mov        al,[ebx-510]
  1897.         mov        wcirc[1],al
  1898.         mov        al,[ebx+2]
  1899.         mov        wcirc[2],al
  1900.         mov        al,[ebx+514]
  1901.         mov        wcirc[3],al
  1902.         mov        al,[ebx+512]
  1903.         mov        wcirc[4],al
  1904.         mov        al,[ebx+510]
  1905.         mov        wcirc[5],al
  1906.         mov        al,[ebx-2]
  1907.         mov        wcirc[6],al
  1908.         mov        al,[ebx-514]
  1909.         mov        wcirc[7],al
  1910.         xor        ebx,ebx
  1911.         mov        bh,byte ptr y
  1912.         mov        bl,byte ptr x
  1913.         add        ebx,offset WLock
  1914.         mov        al,[ebx-512]
  1915.         mov        wcirc[8],al
  1916.         mov        al,[ebx-510]
  1917.         mov        wcirc[9],al
  1918.         mov        al,[ebx+2]
  1919.         mov        wcirc[10],al
  1920.         mov        al,[ebx+514]
  1921.         mov        wcirc[11],al
  1922.         mov        al,[ebx+512]
  1923.         mov        wcirc[12],al
  1924.         mov        al,[ebx+510]
  1925.         mov        wcirc[13],al
  1926.         mov        al,[ebx-2]
  1927.         mov        wcirc[14],al
  1928.         mov        al,[ebx-514]
  1929.         mov        wcirc[15],al
  1930.     }
  1931. };
  1932. inline void WFCirc(byte x,byte y,byte x0,byte y0,byte x1,byte y1){
  1933.     __asm{
  1934.         xor        ebx,ebx
  1935.         mov        bl,x
  1936.         mov        bh,y
  1937.         cmp        bl,x0
  1938.         jne        lb1
  1939.         mov        WMap[ebx-514],1
  1940.         mov        WMap[ebx-2],1
  1941.         mov        WMap[ebx+510],1
  1942.         mov        WLock[ebx-514],1
  1943.         mov        WLock[ebx-2],1
  1944.         mov        WLock[ebx+510],1
  1945. lb1:    cmp        bl,x1
  1946.         jne        lb2
  1947.         mov        WMap[ebx-510],1
  1948.         mov        WMap[ebx+2],1
  1949.         mov        WMap[ebx+514],1
  1950.         mov        WLock[ebx-510],1
  1951.         mov        WLock[ebx+2],1
  1952.         mov        WLock[ebx+514],1
  1953. lb2:    cmp        bh,y0
  1954.         jne        lb3
  1955.         mov        WMap[ebx-514],1
  1956.         mov        WMap[ebx-512],1
  1957.         mov        WMap[ebx-510],1
  1958.         mov        WLock[ebx-514],1
  1959.         mov        WLock[ebx-512],1
  1960.         mov        WLock[ebx-510],1
  1961. lb3:    cmp        bh,y1
  1962.         jne        lb4
  1963.         mov        WMap[ebx+510],1
  1964.         mov        WMap[ebx+512],1
  1965.         mov        WMap[ebx+514],1
  1966.         mov        WLock[ebx+510],1
  1967.         mov        WLock[ebx+512],1
  1968.         mov        WLock[ebx+514],1
  1969. lb4:
  1970.     };
  1971. };
  1972.  
  1973. //Order Type=77
  1974. //╤ΓαδΦ≥ⁿ ± ²≥εΘ ≥ε≈ΩΦ.═σ⌠Φπ τ≡  ±≥ε ≥ⁿ.dir-φα∩≡αΓδσφΦσ,
  1975. //Γ Ωε≥ε≡ε∞ ΣΓΦµσφ≥±  εß┌σΩ≥,Ωε≥ε≡√Θ ∩≡σΣδαπασ≥ Σαφφε∞≤
  1976. //±ΓαδΦ≥ⁿ ± Σε≡επΦ. Γ ²≥ε∞ φα∩≡αΓδσφΦΦ ±ΣΓΦπα≥ⁿ±  δΦ°ⁿ Γ
  1977. //Ω≡αΘφσ∞ ±δ≤≈ασ
  1978. void WMFLink(OneObject* OBJ);
  1979. void OneObject::WMoveFrom(int dir){
  1980.     //Npush++;
  1981.     if(!cpbMoving)return;
  1982.     if(StandTime<3)return;
  1983.     bool initMXY=true;
  1984.     if(int(LocalOrder))
  1985.         if(LocalOrder->OrderType==77)initMXY=false;
  1986.     if(initMXY){
  1987.         Order1* Or1=GetOrdBlock();
  1988.         if(!int(Or1))return;
  1989.         Or1->PrioryLevel=0;
  1990.         Or1->NextOrder=LocalOrder;
  1991.         Or1->OrderType=77;
  1992.         Or1->OrderTime=0;
  1993.         Or1->info.MoveFrom.dir=dir;
  1994.         //if(int(LocalOrder))FreeOrdBlock(LocalOrder);
  1995.         if(int(InLineCom)){
  1996.             FreeAsmLink();
  1997.             //LoadCurAnm(0);
  1998.         };
  1999.         LocalOrder=Or1;
  2000.         Or1->DoLink=&WMFLink;
  2001.         //OrderReport=NULL;
  2002.         //MessageKind=0;
  2003.         //Sender=0xFFFF;
  2004.         //MFLink(this);
  2005.     };
  2006. };
  2007. void WMFLink(OneObject* OBJ){
  2008.     byte Direction=OBJ->Direction;
  2009.     byte dir=OBJ->LocalOrder->info.MoveFrom.dir;
  2010.     if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  2011.     OBJ->InLineCom=0;
  2012.     Order1* Loc1=OBJ->LocalOrder->NextOrder;
  2013.     OBJ->FreeOrdBlock(OBJ->LocalOrder);
  2014.     OBJ->LocalOrder=Loc1;
  2015.     int dx0=idrxw[Direction]<<1;
  2016.     int    dy0=idryw[Direction]<<1;
  2017.     int x=OBJ->x;
  2018.     int y=OBJ->y;
  2019.     if(OBJ->DrawUp){
  2020.         WMemCirc(x,y);
  2021.         WFCirc(x,y,OBJ->destX,OBJ->destY,OBJ->destX1,OBJ->destY1);
  2022.     };
  2023.     bool Dfound=false;
  2024.     int ddr;
  2025.     int tx;
  2026.     int ty;
  2027.     if(WLock[y+dy0][x+dx0]/*||dir==Direction*/){
  2028.         if(rando()<RAND_MAX/2){
  2029.             //Turn right
  2030.             ddr=(Direction+1)&7;
  2031.             int z=0;
  2032.             do{
  2033.                 dx0=idrxw[ddr]<<1;
  2034.                 dy0=idryw[ddr]<<1;
  2035.                 ddr=(ddr+1)&7;
  2036.                 z++;
  2037.                 tx=x+dx0;
  2038.                 ty=y+dy0;
  2039.                 if(tx>=0&&ty>0&&tx<msx&&ty<msy&&!WLock[ty][tx])break;
  2040.             }while(z<8);
  2041.             ddr=(ddr+7)&7;
  2042.             if(z<8)Dfound=true;
  2043.         } else{
  2044.             //Turn left
  2045.             int ddr=(Direction+7)&7;
  2046.             int z=0;
  2047.             do{
  2048.                 dx0=idrxw[ddr]<<1;
  2049.                 dy0=idryw[ddr]<<1;
  2050.                 ddr=(ddr+7)&7;
  2051.                 z++;
  2052.             }while(WLock[y+dy0][x+dx0]&&z<8);
  2053.             ddr=(ddr+1)&7;
  2054.             if(z<8)Dfound=true;
  2055.         };
  2056.     }else{
  2057.         Dfound=true;
  2058.         ddr=Direction;
  2059.     };
  2060.     if(!Dfound&&!WLock[y+dy0][x+dx0]/*&&dir==Direction*/){
  2061.         Dfound=true;
  2062.         ddr=Direction;
  2063.         dx0=idrxw[ddr]<<1;
  2064.         dy0=idryw[ddr]<<1;
  2065.     };
  2066.     if(!Dfound){
  2067.         int z=rando();
  2068.         if(z&1){
  2069.             z=z>>1;
  2070.             //Turn right
  2071.             ddr=(Direction+(z&1))&7;
  2072.             int z=0;
  2073.             do{
  2074.                 dx0=idrxw[ddr]<<1;
  2075.                 dy0=idryw[ddr]<<1;
  2076.                 ddr=(ddr+1)&7;
  2077.                 z++;
  2078.                 tx=x+dx0;
  2079.                 ty=y+dy0;
  2080.                 if(tx>=0&&ty>0&&tx<msx&&ty<msy&&!WMap[ty][tx])break;
  2081.             }while(z<8);
  2082.             ddr=(ddr+7)&7;
  2083.             if(z<8)Dfound=true;
  2084.         } else{
  2085.             //Turn left
  2086.             z=z>>1;
  2087.             int ddr=(Direction+8-(z&1))&7;
  2088.             int z=0;
  2089.             do{
  2090.                 dx0=idrxw[ddr]<<1;
  2091.                 dy0=idryw[ddr]<<1;
  2092.                 ddr=(ddr+7)&7;
  2093.                 z++;
  2094.             }while(WMap[y+dy0][x+dx0]&&z<8);
  2095.             ddr=(ddr+1)&7;
  2096.             if(z<8)Dfound=true;
  2097.         };
  2098.         if(tx>=0&&tx<msx&&ty>=0&&ty<msy)Dfound=true;
  2099.     };
  2100.     if(Dfound){
  2101.         int difR=8+ddr-Direction;
  2102.         difR&=7;
  2103.         int difL=8+Direction-ddr;
  2104.         difL&=7;
  2105.         byte minDr=difR<difL?difR:difL;
  2106.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  2107.         
  2108.         OBJ->LoadAnimation(0,OBJ->AnmStandKind,0);
  2109.         OBJ->LoadAnimation(1,OBJ->AnmGoKind,0);
  2110.         AddAsk(OBJ->Index,x,y,dx0,dy0);
  2111.     };
  2112.     if(OBJ->DrawUp)
  2113.         WReMemCirc(x,y);
  2114. };