home *** CD-ROM | disk | FTP | other *** search
/ WarCraft 2000 - Nuclear Epidemic / W2000.nrg / SOURCE.War2000 / Nation.cpp < prev    next >
C/C++ Source or Header  |  1998-09-24  |  83KB  |  3,568 lines

  1. /*
  2.  *
  3.  *  MAIN COMMAND MODULE. (Andrew)
  4.  *
  5.  */
  6. /* 1) ╟απ≡≤τΩα εß≡ατεΓ ∞εφ±≥≡εΓ Φτ ±∩Φ±Ωα Γ ⌠αΘδσ monsters.lst
  7.  * 2)╤ετΣαφΦσ φα÷ΦΦ - ταπ≡≤τΩα:
  8.  * nation.gac - Global Animation Collection
  9.  * nation.gmc - Global Monsters Collection
  10.  */    
  11. #include "ddini.h"
  12. #include "ResFile.h"
  13. #include "FastDraw.h"
  14. #include "mgraph.h"
  15. #include "mouse.h"
  16. #include "menu.h"
  17. #include "MapDiscr.h"
  18. #include "fog.h"
  19. #include "Megapolis.h"
  20. #include "FlyObj.h"
  21. #include <assert.h>
  22. #include "walls.h"
  23. #include "mode.h"
  24. #include "GSound.h"
  25. int NMyUnits;
  26. int NThemUnits;
  27. extern int tmtmt;
  28. extern int HREQRADIUS;
  29. extern word FlyMops[256][256];
  30. extern byte NPresence[64][64];
  31. void ShowFog(OneObject* ZZ);
  32. //byte CreateExObjR(Weapon* Wep,short x,short y,
  33. //                 short dx,short dy,short v,byte Mask,OneObject* Send,word Dist);
  34. //byte CreateExObjDPointR(Weapon* Wep,short x,short y,
  35. //                 short dx,short dy,short v,byte Mask,OneObject* Send,byte dsx,byte dsy,word Range);
  36. word MAXOBJECT;
  37. //┼±δΦ ∩ε±≥≤∩ασ≥ ∩≡ΦΩατ ≤≡εΓφ <16 Φ ≥Γα≡ⁿ, Ωε≥ε≡≤■
  38. //φ≤µφε α≥αΩεΓα≥ⁿ ±≥εΦ≥ Σαδⁿ°σ ²≥επε ≡α±±≥ε φΦ , ≥ε
  39. //∩≡ΦΩατ φσ Γ√∩εδφ σ≥± 
  40. static MaxReplyDistance=50;
  41.  
  42. int PathAsks;
  43. const int drr[9]={7,6,5,0,0,4,1,2,3};
  44. const byte drrb[9]={7,6,5,0,0,4,1,2,3};
  45. const idrx[8]={0,1,1,1,0,-1,-1,-1};
  46. const idry[8]={-1,-1,0,1,1,1,0,-1};
  47. //╠α±±ΦΓ Σδ  ε∩≥Φ∞Φτα÷ΦΦ ∩≤≥Φ
  48. static int OptA[256][256];
  49. static SIndex;
  50. int counter;
  51. static byte xi[256][256];
  52. static byte yi[256][256];
  53. byte RNTB[64][256];
  54. //HUGE ARRAY!!!!!!!!!!!!
  55. OneObject OBJECTS[8192];
  56. //╬≡παφΦτα÷Φ  ε≈σ≡σΣΦ φα Γ√∩εδφσφΦσ Σεδπεπε ∩≡ΦΩατα
  57. word ComStc[StSize];
  58. word StHead;
  59. word StTile;
  60. void MCHK(){
  61. /*    if(int(Group[150]->LocalOrder)){
  62.         if(Group[150]->LocalOrder->OrderType==2&&
  63.             Group[150]->LocalOrder->info.MoveToXY.y==0){
  64.             int uuu=0;
  65.             return;
  66.         };
  67.     }*/
  68. };
  69. void InitStack(){
  70.     StHead=0;
  71.     StTile=0;
  72. };
  73. bool CheckAttAbility(OneObject* OB,word Patient){
  74.     if(OB&&Patient!=0xFFFF){
  75.         OneObject* EN=Group[Patient];
  76.         if(!EN)return false;
  77.         GeneralObject* EGO=EN->Ref.General;
  78.         if(EN->NMask&OB->NMask)return false;
  79.         GeneralObject* GO=OB->Ref.General;
  80.         if(GO->WATT&&!(EN->OnWater||EGO->OnCost))return false;
  81.         if(EN->Media==2&&!GO->AATT)return false;
  82.         if(EGO->Submarine&&!GO->UATT)return false;
  83.         if(EN->OnWater&&!GO->SATT)return false;
  84.         return true;
  85.     }else{
  86.         return false;
  87.     };
  88.  
  89. };
  90. word PopCmd(){
  91.     if(StHead!=StTile){
  92.         int z=StTile;
  93.         StTile++;
  94.         StTile=StTile&StMask;
  95.         OneObject* OBJ=Group[ComStc[z]];
  96.         if(int(OBJ)){
  97.             OBJ->Push=false;
  98.             return ComStc[z];
  99.         }else return 0xFFFF;
  100.     } else return 0xFFFF;
  101. };
  102. void PushCmd(word Cmd){
  103.     if(Group[Cmd]->Push)return;
  104.     ComStc[StHead]=Cmd;
  105.     StHead++;
  106.     StHead=StHead&StMask;
  107.     Group[Cmd]->Push=true;
  108. };
  109. void CarryOutOrder(){
  110.     int i;
  111.     int TimerX=FreeTime;
  112.     do{
  113.         i=PopCmd();
  114.         TimerX-=10;
  115.         if(i==0xFFFF)return;
  116.         OneObject* Ob=Group[i];
  117.         Order1* Ord=Ob->LocalOrder;
  118.         
  119.         if(!int(Ob->InLineCom)&&int(Ob)&&int(Ord))Ord->DoLink(Ob);
  120.         //{
  121.         //    if(Ord->OrderType==2)Ob->SendTo(Ord->info.MoveToXY.x,
  122.         //                              Ord->info.MoveToXY.y,
  123.         //                              Ord->PrioryLevel+128);
  124.         //}
  125.     }while(TimerX>0);
  126. };
  127. RLCTable MImage[maximage];
  128. RLCTable miniMImage[maximage];
  129. int MaxImage;
  130. void Err(LPCSTR s)
  131. {
  132.     MessageBox(hwnd,s,"Nation loading failed...",MB_ICONWARNING|MB_OK);
  133. };
  134. void LoadMonsters(){
  135.     FILE* f=fopen("monsters.lst","r");
  136.     char c[64];
  137.     char cc[64];
  138.     for(int i=0;!feof(f);i++){
  139.         fscanf(f,"%s",c);
  140.         strcpy(cc,c);
  141.         strcat(c,".rlc");
  142.         strcat(cc,".rlx");
  143.         if(c[0]!=0)LoadRLC(c,&MImage[i]);
  144.         if(cc[0]!=0)LoadRLC(cc,&miniMImage[i]);
  145.     };
  146.     ADDSUMM(MImage,1024);
  147.     MaxImage=i;
  148.     for(byte j=0;j<64;j++){
  149.         byte q=0;
  150.         for(int t=0;t<256;t++){
  151.             RNTB[j][t]=q;
  152.             q++;
  153.             if(q>j)q=0;
  154.         };
  155.     };
  156. };
  157.  
  158. //╟απ≡≤τΩα φα÷ΦΦ Φτ ⌠αΘδα
  159. void Nation::CreateNation(LPCSTR NationFile,byte Mask,byte NI){
  160.     char tmp[32];
  161.     NMask=Mask;
  162.     CITY=NULL;
  163.     NNUM=NI;
  164.     NGidot=0;
  165.     NFarms=0;
  166.     CasheSize=0;
  167.     strcpy(tmp,NationFile);
  168.     strcat(tmp,".gac");
  169.     ResFile f=RReset(tmp);
  170.     if(IOresult())Err("Can't open global animation collection.");
  171.     int i;
  172.     RBlockRead(f,&i,4);
  173.     if(i!=0x1B434147)Err("Incorrect format GAC.");
  174.     RBlockRead(f,&NOct,4);
  175.     RBlockRead(f,&NSlides,4);
  176.     Animations=(Octant*)malloc(NOct*sizeof Animation);
  177.     Slides=(OneSlide*)malloc(NSlides*sizeof  OneSlide);
  178.     RBlockRead(f,Animations,NOct*sizeof Animation);
  179.     RBlockRead(f,Slides,NSlides*sizeof  OneSlide);
  180.     for(i=0;i<NOct*8;i++) 
  181.         Animations[i].Movie=(OneSlide*)(
  182.         2*int(Animations[i].Movie)+int(Slides));
  183.     RClose(f);
  184.     ADDSUMM(Animations,NOct*sizeof Animation);
  185.     ADDSUMM(Slides,NSlides*sizeof  OneSlide);
  186.     strcpy(tmp,NationFile);
  187.     strcat(tmp,".gmc");
  188.     f=RReset(tmp);
  189.     if(IOresult())Err("Can't open GMC.");
  190.     RBlockRead(f,&i,4);
  191.     if(i!=0x1B434D47)Err("Incorrect GMC format.");
  192.     RBlockRead(f,&NMon,4);
  193.     int StrSize;
  194.     RBlockRead(f,&StrSize,4);
  195.     RBlockRead(f,&NFinf,4);
  196.     Finf=(MoreAnimation*)malloc(NFinf*8);
  197.     for(i=0;i<NMon;i++){
  198.         Mon[i]=new Visuals;
  199.         RBlockRead(f,&Mon[i]->NameIndex,StrSize);
  200.         Mon[i]->lpFAnim=(MoreAnimation*)(int(Finf)+int(Mon[i]->lpFAnim));
  201.     };
  202.     RBlockRead(f,Finf,NFinf*8);
  203.     for(int j=0;j<NFinf;j++)
  204.             Finf[j].Anm=
  205.               (Octant*)(int(Finf[j].Anm)+int(Animations));
  206.     ADDSUMM(Finf,NFinf*8);
  207.     RClose(f);
  208.     PathAsks=0;
  209.     memset(&PACount,0,sizeof PACount);
  210.     memset(&PAble,0,sizeof PAble);
  211. };
  212. word LastObject;
  213. //╤ετΣα≥ⁿ ∩ατσ∞φ√Θ εß·σΩ≥ ≥Φ∩α ∞εφ±Φ≡α ± Ωεε≡ΣΦφα≥α∞Φ (x,y)
  214. //Φ φε∞σ≡ε∞ n Γ ≥αßδΦ÷σ ∞εφ±≥≡εΓ ΣαφφεΘ φα÷ΦΦ
  215. bool Nation::CreateTerrainAt(int x,int y,int n){
  216.     LastObject=0xFFFF;
  217.     if(Mon[n]->OnWater){
  218.         return CreateOnWater(x,y,n);
  219.     };
  220.     if(Mon[n]->OnAir){
  221.         return CreateOnFly(x,y,n);
  222.     };
  223.     if( Mops[y][x]!=0xFFFF||LLock[y][x])return false;
  224.     for(int i=0;i<MaxObj&&int(Group[i]);i++);
  225.     if(i>MaxObj)return false;
  226.     if(n>=NMon) return false;
  227.     if(i>=MAXOBJECT)MAXOBJECT=i+1;
  228.     LastObject=i;
  229.     Group[i]=OBJECTS+i;
  230.     Cell8x8* CELL=&TCInf[NNUM][y>>2][x>>2];
  231.     OneObject* G=Group[i];
  232.     GeneralObject* GO=Mon[n];
  233.     AddOrderEffect(x,y,GO->BornSound);
  234.     CELL->UnitsAmount[GO->Kind]++;
  235.     G->DefaultSettings(GO);
  236.     G->Media=0;
  237.     G->Teleport=false;
  238.     G->capTeleport=GO->Teleport;
  239.     G->OnWater=false;
  240.     G->Kind=GO->Kind;
  241.     G->VisRadius=GO->VisRadius;
  242.     G->VisSpots=GO->VisSpots;
  243.     G->SpotType=GO->SpotType;
  244.     G->SpotSize=GO->SpotSize;
  245.     G->DangerZone=GO->DangerZone;
  246.     G->NoSearchVictim=GO->NoSearchVictim;
  247.     G->NoAnswer=GO->NoAnswer;
  248.     G->NeedNoHelp=GO->NeedNoHelp;
  249.     G->Nat=this;
  250.     G->Ready=true;
  251.     G->wepX=GO->wepX;
  252.     G->wepY=GO->wepY;
  253.     G->MaxDelay=GO->delay;
  254.     G->delay=0;
  255.     G->NearBase=0xFFFF;
  256.     G->capBase=GO->cpbBase;
  257.     G->RStage=0;
  258.     G->RType=0;
  259.     G->RAmount=0;
  260.     G->NNUM=NNUM;
  261.     G->NIndex=n;
  262.     G->AnmStandKind=0;
  263.     G->AnmGoKind=1;
  264.     G->capBuild=GO->cpbBuild;
  265.     G->GroupIndex=NULL;
  266.     G->cpbMoving=GO->cpbMoving;
  267.     if(!GO->SizeX)GO->SizeX=1;
  268.     if(!GO->SizeY)GO->SizeY=1;
  269.     G->Lx=GO->SizeX;
  270.     G->Ly=GO->SizeY;
  271.     G->TempFlag=false;
  272.     G->Mobilised=false;
  273.     G->Wars=NULL;
  274.     G->Index=i;
  275.     Mops[y][x]=i;
  276.     Visuals* m;
  277.     m=(Visuals*)Mon[n];
  278.     G->Selected=false;
  279.     G->Borg=false;
  280.     G->Life=m->info.Basic.MaxLife;
  281.     G->MaxLife=m->info.Basic.MaxLife;
  282.     G->Ref.Visual=m;
  283.     G->x=x;
  284.     G->y=y;
  285.     G->CrowdRef=NULL;
  286.     G->Push=false;
  287.     LLock[y][x]=true;
  288.     IncLock(x,y);
  289.     G->Direction=rando() & 7;
  290.     memset(&(G->ARegs),0,sizeof G->ARegs);
  291.     G->LoadAnimation(0,0,0);
  292.     G->LoadCurAnm(0);
  293.     G->LocalOrder=NULL;
  294.     //G->OrderReport=NULL;
  295.     //G->MessageFlags=0;
  296.     G->PrioryLevel=0;
  297.     //G->MessageKind=0;
  298.     G->InLineCom=NULL;
  299.     G->LineOffset=0;
  300.     G->Ticks=0;
  301.     G->TicksPerChange=10;
  302.     G->Wait=0;
  303.     G->Addx=0;
  304.     G->Addy=0;
  305. //    G->inMotion=false;
  306.     G->Npush=0;
  307.     G->StandTime=100;
  308.     G->Sdoxlo=false;
  309.     G->Weap=Mon[n]->Weap;
  310.     G->NMask=NMask;
  311.     G->Important=false;
  312.     G->EnemyDist=5000;
  313.     G->Attack=false;
  314.     G->StandGround=false;
  315.     G->EnemyID=0xFFFF;
  316.     G->Egoist=false;
  317.     if(CITY->IntellectEnabled){
  318.         if(GO->CanAttWall)G->DoWalls=true;
  319.         G->Use_AI=true;
  320.         G->NeedNoHelp=true;
  321.     };
  322.     NGidot++;
  323.     return true;
  324. };
  325. //╟απ≡≤τΦ≥ⁿ αφΦ∞α÷Φ■ ± Σαφφ√∞Φ ∩εΩατα≥σδ ∞Φ Γ εΣΦφ Φτ 5-≥Φ Γφ≤≥≡.
  326. //≡σπΦ±≥≡εΓ 
  327. void OneObject::LoadAnimation(int Reg,byte WhatFor,word Kind){
  328.     if(ARegs[Reg].Kind==Kind&&ARegs[Reg].WhatFor==WhatFor&&int(ARegs[Reg].Anm))return;
  329.     MoreAnimation* An=Ref.General->lpFAnim;
  330.     int NAn=Ref.General->NAnm;
  331. #ifdef DEBLEVEL1
  332.     assert(NAn<64&&NAn>0);
  333.     assert(WhatFor<32);
  334. #endif
  335.     for(int i=0;i<NAn&&(WhatFor!=An[i].WhatFor||Kind!=An[i].Kind);i++);
  336.     if(i<NAn){
  337.         ARegs[Reg].Kind=Kind;
  338.         ARegs[Reg].WhatFor=WhatFor;
  339.         ARegs[Reg].Anm=An[i].Anm;
  340.     } else{
  341.         for(int i=0;i<NAn&&(WhatFor!=An[i].WhatFor);i++);
  342.         if(i<NAn){
  343.             ARegs[Reg].Kind=Kind;
  344.             ARegs[Reg].WhatFor=WhatFor;
  345.             ARegs[Reg].Anm=An[i].Anm;
  346.         }
  347. #ifdef DEBLEVEL1 
  348.         else assert(0);
  349. #else
  350.         ;
  351.         ARegs[Reg].Kind=0;
  352.         ARegs[Reg].WhatFor=0;
  353.         ARegs[Reg].Anm=An[0].Anm;
  354. #endif
  355.     };
  356.  
  357. };
  358. //╬ß≡αßε≥Ωα ∩σ≡σΓσ≡φ≤≥√⌡ ±∩≡αΘ≥εΓ
  359. void OneObject::LoadCurAnm(int reg){
  360. #ifdef DEBUGLEVEL1
  361.     assert(Direction<8);
  362.     assert(reg<4);
  363. #endif
  364.     if(Direction>4){
  365.         CurAnm=&(ARegs[reg].Anm[8-Direction]);
  366.         Invert=true;
  367.     } else{
  368.         CurAnm=&(ARegs[reg].Anm[Direction]);
  369.         Invert=false;
  370.     };
  371.     CurrentSprite=0;
  372.     Ticks=0;
  373.     TicksPerChange=1;
  374. };
  375. void OneObject::FreeAsmLink(){
  376.     if(!int(InLineCom))return;
  377.     FreeAsmBlock(InLineCom);
  378.     char* k;
  379.     do{
  380.         memcpy(&k,
  381.             &((char*)InLineCom)[OneAsmSize-4],4);
  382.         if(k!=0)FreeAsmBlock(k);
  383.         InLineCom=k;
  384.     }while (int(k)!=0);
  385.     InLineCom=NULL;
  386.     LineOffset=0;
  387. };
  388. //╬±φεΓφ√σ ±≥≡≤Ω≥≤≡√ Σδ  εß≡αßε≥ΩΦ ∩σ≡σ∞σ∙σφΦΘ
  389. //τα∩≡ε± φα ∩σ≡σ∞σ∙σφΦσ
  390. struct AskMove{
  391.     word ReqID;//ΦφΣσΩ± ∩σ≡σ∞σ∙ασ∞επε
  392.     word PreID;//ΦφΣσΩ± µαµΣ≤∙σπε Σε≡Γα≥ⁿ±  Γ ²≥≤ Ωδσ≥Ω≤
  393.     byte x;
  394.     byte y;
  395.     char dx;
  396.     char dy;
  397. };
  398. int NAsk;//╩εδΦ≈σ±≥Γε τα∩≡ε±εΓ
  399. AskMove Ask[8192];//╠α±±ΦΓ τα∩≡ε±εΓ
  400. bool FailLink[8192];//╠α±±ΦΓ φσ≡ατ≡σ°σφφ√⌡ ∩σ≡σ∞σ∙σφΦΘ
  401. word CurInd;
  402. word IDMap[256][256];
  403. word RQMap[256][256];//:3-τα∩σ∙σφφεσ φα∩≡αΓδσφΦσ ..
  404.                      //:13-φε∞σ≡ Γ ≥αßδΦ÷σ τα∩≡ε±εΓ
  405. //─εßαΓΦ≥ⁿ τα∩≡ε± Γ ±Φ±≥σ∞≤ τα∩≡ε±εΓ φα ∩σ≡σ∞σ∙σφΦσ
  406. void AddAsk(word ReqID,byte x,byte y,char zdx,char zdy){
  407.     //DEBUGGING
  408.     OneObject* OB=Group[ReqID];
  409. #ifdef DEBLEVEL1
  410.     assert(OB->x==x&&OB->y==y);
  411.     assert(!OB->AskMade);
  412.     assert((!OB->OnWater)&&abs(zdx)<2&&abs(zdy)<2);
  413.     if(OB->OnWater) assert(abs(zdx)<3&&abs(zdy)<3);
  414.     else assert(abs(zdx)<2&&abs(zdy)<2);
  415. #endif
  416.     OB->AskMade=true;
  417.     //ENDDEBUG
  418.     __asm{
  419. //        inc        NAsk
  420.         mov        eax,NAsk
  421.         shl        eax,3
  422.         add        eax,offset Ask
  423.         mov        bx,ReqID
  424.         mov        word ptr [eax],bx
  425.         mov        word ptr [eax+2],0FFFFh
  426.         mov        bl,x
  427.         mov        bh,y
  428.         mov        word ptr [eax+4],bx
  429.         mov        bl,zdx
  430.         mov        bh,zdy
  431.         mov        word ptr [eax+6],bx
  432.         inc        NAsk
  433.     };
  434. };
  435. //╬ß≡αßε≥Ωα τα∩≡ε±εΓ, ±φα≈αδα ε±ΓεßεµΣασ∞ Γ±σ ±≥α≡√σ Ωδσ≥ΩΦ
  436. //∩ε≥ε∞ τα∩εδφ σ∞ Φ ∩≡εΓσ≡ σ∞
  437. void HandleAsks(){
  438.     if(!NAsk)return;
  439.     __asm{
  440.         cmp        CurInd,0
  441.         jne        NoFill
  442.         mov        edi,offset IDMap
  443.         mov        ecx,32768
  444.         cld    
  445.         xor        eax,eax
  446.         rep        stosd
  447. NoFill:
  448.         inc        CurInd
  449.     };
  450.     int NN=NAsk;
  451.     int    ZZ=0;
  452.     //ε±ΓεßεµΣασ∞ ∞σ±≥ε
  453.     __asm{
  454.         mov    esi,offset Ask
  455.         xor        eax,eax
  456.         xor        ecx,ecx
  457.         xor        ebx,ebx
  458.         xor        edx,edx
  459. C1Begin:
  460.         mov        al,[esi+6]//dx
  461.         inc        al
  462.         mov        ah,al
  463.         shl        al,1
  464.         add        al,ah
  465.         add        al,[esi+7]//dy
  466.         inc        al
  467.         xor        ah,ah
  468.         mov        bl,byte ptr [drrb+eax]//direction
  469.         mov        cx,[esi+4]//x,y=>offset
  470.         mov        ax,CurInd
  471.         mov        [IDMap+ecx*2],ax
  472.         add        bl,4
  473.         and        bl,7
  474.         mov        dx,word ptr ZZ
  475.         shl        dx,3
  476.         add        dl,bl
  477.         mov        [RQMap+ecx*2],dx
  478.         mov        byte ptr [LLock+ecx],0//≡ατßδεΩΦ≡εΓαδΦ ±≥α≡εσ ∩εδεµσφΦσ
  479.         add        esi,8//size of Ask[0] 
  480.         inc        ZZ
  481.         dec        NN
  482.         jnz        C1Begin
  483.         //ε≈Φ∙ασ∞ ∞α±±ΦΓ ±ßεσΓ
  484.         mov        edi,offset FailLink
  485.         mov        ecx,NAsk
  486.         shr        ecx,2
  487.         inc        ecx
  488.         cld
  489.         mov        eax,01010101h
  490.         rep        stosd
  491.         //╧≡εΓσ≡ σ∞ Γετ∞εµφε±≥ⁿ ∩σ≡σ∞σ∙σφΦ 
  492.         mov        eax,NAsk
  493.         mov        NN,eax
  494.         mov        esi,offset Ask
  495.         xor        ecx,ecx
  496.         xor        eax,eax
  497.         mov        ZZ,0
  498. C2Begin:
  499.  
  500.         mov        cx,[esi+4]//x,y -> offset
  501.         add        cl,[esi+6]//x+dx,y+dy -> offset
  502.         add        ch,[esi+7]
  503.         cmp        byte ptr [LLock+ecx],0
  504.         jnz        C2isLocked
  505.         mov        ax,word ptr CurInd
  506.         cmp        word ptr [IDMap+ecx*2],ax
  507.         jne        C2notLocked
  508.         //direction
  509.         mov        dx,[RQMap+ecx*2]
  510.         and        dl,7
  511.         mov        al,[esi+6]
  512.         inc        al
  513.         mov        ah,al
  514.         shl        al,1
  515.         add        al,ah
  516.         add        al,[esi+7]
  517.         inc        al
  518.         xor        ah,ah
  519.         mov        al,[drrb+eax]//=direction
  520.         cmp        al,dl
  521.         je        C2isLocked //∩σ≡σ⌡εΣ Γ ²≥ε∞ φα∩≡αΓδσφΦΦ τα∩≡σ∙σφ
  522.         //±≥αΓΦ∞ ±±√δΩ≤ φα Σαφφεπε ∞εφ±≥≡α Γ ∩εδσ PreID 
  523.         //≤ ∞εφ±≥≡α, Ωε≥ε≡√Θ ≡αφσσ ταφΦ∞αδ ²≥≤ Ωδσ≥Ω≤
  524.         mov        dx,[RQMap+ecx*2]
  525.         and        edx,0FFF8h
  526.         mov        ax,word ptr ZZ
  527.         mov        word ptr [Ask+2+edx],ax
  528. C2notLocked:
  529.         mov        [LLock+ecx],1//ßδεΩΦ≡≤σ∞ Ωδσ≥Ω≤
  530.         inc        ZZ
  531.         add        esi,8
  532.         dec        NN
  533.         jnz        C2Begin
  534.         jmp        CycEnd
  535.         //╩δσ≥Ωα ταßδεΩΦ≡εΓαφα, ε∩≡σΣσδ σ∞ ∞εφ±≥≡εΓ,∩σ≡σ∞σ∙σφΦσ 
  536.         //Ωε≥ε≡√⌡ τα∩≡σ∙σφε ε≥φ√φσ
  537. C2isLocked:
  538.         mov        ax,[esi+4]
  539.         mov        byte ptr [LLock+eax],1
  540.         mov        ax,word ptr ZZ
  541.         xor        edx,edx
  542. FailLoop:
  543.         mov        byte ptr [FailLink+eax],0
  544.         mov        bx,word ptr [Ask+2+eax*8]
  545.         mov        word ptr [Ask+2+eax*8],0FFFFh
  546.         mov        dx,word ptr [Ask+4+eax*8]
  547.         mov        [LLock+edx],1//ßδεΩΦ≡≤σ∞ ±≥α≡≤■ ∩ετΦ÷Φ■
  548.         mov        ax,bx
  549.         cmp        ax,0FFFFh
  550.         jne        FailLoop
  551.         inc        ZZ
  552.         add        esi,8
  553.         dec        NN
  554.         jnz        C2Begin
  555. CycEnd:
  556.     };
  557.     //≡στ≤δⁿ≥α≥ε∞ Γ√°σ≤Ωαταφφεπε ∩≡ε±≥≡αΣα ß√δε
  558.     //∩≡αΓΦδⁿφεσ τα∩εδφσφΦσ ∞α±±ΦΓα FailLink,
  559.     //≥ε σ±≥ⁿ ε∩≡σΣσδσφΦσ, ΩαΩΦ∞ ∞εφ±≥≡α∞ ∩σ≡σ∞σ∙σφΦσ 
  560.     //≡ατ≡σ°σφε, α ΩαΩΦ∞ φσ≥
  561. };
  562. void PrepareProcessing(){
  563.     NAsk=0;
  564.     //Only for DEBUGGIONG 
  565.     for(int i=0;i<MAXOBJECT;i++){
  566.         OneObject* OB=Group[i];
  567.         if(OB)OB->AskMade=false;
  568.     };
  569. };
  570. inline void Spot(int x,int y){
  571.     if(x>0&&y>0&&x<msx&&y<msy){
  572.         __asm{
  573.             xor        eax,eax
  574.             mov        al,byte ptr x
  575.             mov        ah, byte ptr y
  576.             shl        eax,1
  577.             mov        word ptr[fmap+eax],16383;
  578.         };
  579.     };
  580. };
  581. void HandleDWall(OneObject* OB);
  582. void OneObject::MakePreProcess(){
  583.     if(Media||Absent)return;
  584.     if(capMagic){
  585.         if(Magic<capMagic&&!(tmtmt&7))Magic++;
  586.     };
  587.     ShowFog(this);
  588.     if(RefreshLife&&Life<MaxLife){
  589.         if(!(tmtmt&3))Life++;
  590.     };
  591.     if(NNUM==MyNation){
  592.         int x0,y0,dx,dx1;
  593.         switch(SpotType){
  594.         case 0:
  595.             if(Lx>1){
  596.             for(byte ux=0;ux<Lx;ux++)
  597.                 for(byte uy=0;uy<Ly;uy++)
  598.                     Spot(x+ux,y+uy);
  599.             }else Spot(x,y);
  600.             break;
  601.         case 1:
  602.             x0=x+(Lx>>1);
  603.             y0=y+(Ly>>1);
  604.             dx=SpotSize;
  605.             Spot(x0,y0);
  606.             Spot(x0+dx,y0);
  607.             Spot(x0-dx,y0);
  608.             Spot(x0,y0+dx);
  609.             Spot(x0,y0-dx);
  610.             break;
  611.         case 2:
  612.             x0=x+(Lx>>1);
  613.             y0=y+(Ly>>1);
  614.             dx=SpotSize;
  615.             dx1=dx-(dx>>2);
  616.             Spot(x0,y0);
  617.             Spot(x0+dx,y0);
  618.             Spot(x0-dx,y0);
  619.             Spot(x0,y0+dx);
  620.             Spot(x0,y0-dx);
  621.             Spot(x0+dx1,y0+dx1);
  622.             Spot(x0-dx1,y0-dx1);
  623.             Spot(x0+dx1,y0-dx1);
  624.             Spot(x0-dx1,y0+dx);
  625.             break;
  626.         };
  627.     };
  628.     if(MTime){
  629.         if(MTime==1){
  630.             xForce=16;
  631.         };
  632.         MTime--;
  633.     };
  634.     if(!NoSearchVictim)SearchVictim();
  635.     if(DoWalls)HandleDWall(this);
  636.     if(delay)delay--;
  637.     else{
  638.         if(AntiNuc){
  639.             if(RAmount<20)RAmount++;
  640.             delay=3000;
  641.         };
  642.     };
  643.     Ticks++;
  644.     if(Ticks<TicksPerChange){
  645.         Ticks++;
  646.         if(TicksPerChange!=255)return;
  647.     };
  648.     Ticks=0;
  649.         int Nsp=CurAnm->count-1;
  650.         if(CurrentSprite<Nsp&&TicksPerChange!=255){
  651.             CurrentSprite++;
  652.             //Ticks=0;
  653.             //TicksPerChange=1;
  654.             return;
  655.         };
  656.         if(Sdoxlo){
  657.             if(TicksPerChange==250){;
  658.                  Died[y][x]=0xFFFF;
  659.                  OneObject yy=*Group[Index];
  660.                  OneObject* OO=Group[Index];
  661.                  Group[Index]=NULL;
  662.                  OneObject OOO=*OO;
  663.                  //free(OO);
  664.                  return;
  665.             }else{
  666.                 TicksPerChange=250;
  667.                 return;
  668.             };
  669.         };
  670.         if(TicksPerChange!=255)CurrentSprite=0;
  671.         Addx=0;
  672.         Addy=0;
  673.         Removed=false;
  674.         StandTime++;
  675.         if(Life<=0){
  676.             Die();
  677.             return;
  678.         };
  679.         if(Life==1&&(!capBuilding)&&rando()<1024)Life=0;
  680.         //if(!Important)
  681.         Order1* LO=LocalOrder;
  682.         if(!LO){
  683.             PrioryLevel=0;
  684.             if(Repair){
  685.                 WaitForRepair();
  686.             };
  687.         };
  688.         if(int(InLineCom)){
  689.             if(LO&&LO->OrderType>127){
  690.                 //FreeAsmLink();
  691.                 LocalOrder->DoLink(this);
  692.             };
  693.             bool    Done;
  694.             if(InLineCom)
  695.             do{
  696.                 byte* p=(byte*)(int(InLineCom)+LineOffset);
  697.                 byte b=p[0];
  698.                 Done=false;
  699.                 switch(b){
  700.                 //case 0:
  701.                 case 1:
  702.                     //Return
  703.                     FreeAsmLink();    
  704.                     //MessageFlags=MessageFlags|2;
  705.                     Done=true;
  706.                     break;
  707.                 case 3:
  708.                     //TakeNextOrder();
  709.                     {
  710.                         if(int(LocalOrder)){
  711.                             Order1* Loc1=LocalOrder->NextOrder;
  712.                             FreeOrdBlock(LocalOrder);
  713.                             LocalOrder=Loc1;
  714.                         };
  715.                         LineOffset++;
  716.                         Done=true;
  717.                     };
  718.                     break;
  719.                 case 4:
  720.                     //set coordinates
  721.                     //[04][dx][dy]
  722.                     assert(x>0&&x<=msx&&y>0&&y<=msy);
  723.                     AddAsk(Index,x,y,p[1],p[2]);
  724.                     LineOffset+=3;
  725.                     Done=true;
  726.                     Removed=true;
  727.                     break;
  728.                 case 5:
  729.                     //set direction
  730.                     Direction=p[1];
  731.                     LineOffset+=2;
  732.                     break;
  733.                 case 6:
  734.                     LoadAnimation(p[1],p[2],p[3]);
  735.                     LineOffset+=5;
  736.                     break;
  737.                 case 7:
  738.                     //jump...
  739.                     {int pp=*(int*)(int(p)+1);
  740.                     FreeAsmBlock(InLineCom);
  741.                     LineOffset=0;
  742.                     InLineCom=(char*)pp;};
  743.                     break;
  744.                 case 8:
  745.                     //Use register to animate
  746.                     LoadCurAnm(p[1]);
  747.                     Ticks=0;
  748.                     TicksPerChange=1;
  749.                     LineOffset+=2;
  750.                     Done=true;
  751.                     break;
  752.                 default:
  753.                     assert(0);
  754.                     break;
  755.                 };
  756.             } while(!Done);
  757.             //if(int(OrderReport))OrderReport(this);
  758.             //OneObject* OBJ=Group[0];
  759.             //if(OBJ->Removed&&(OBJ->InLineCom)[OBJ->LineOffset]!=4)
  760.             //    int ggg=0;
  761.             //if(LO&&LO->OrderType>127&&!AskMade){
  762.             //    //FreeAsmLink();
  763.             //    LocalOrder->DoLink(this);
  764.             //};
  765.         } else{ 
  766.             if(TicksPerChange!=255)LoadCurAnm(0);
  767.             Important=false;
  768.             if(int(LocalOrder)){
  769.                 if(LocalOrder->OrderTime&&!Push){
  770.                     PushCmd(Index);
  771.                     return;
  772.                 };
  773.                 LocalOrder->DoLink(this);
  774. //                if(LocalOrder->OrderType==77)
  775. //                    MoveFrom(LocalOrder->info.MoveFrom.dir);
  776.             } else    if(TicksPerChange!=255)CurrentSprite=0;
  777.         };
  778. };
  779. void MakePostProcess(){
  780.     HandleAsks();
  781.     for(int i=0;i<NAsk;i++){
  782.         AskMove ASK=Ask[i];
  783.         OneObject* OBJ=Group[ASK.ReqID&8191];
  784.         if(FailLink[i]){
  785.             byte ax=ASK.x;
  786.             byte ay=ASK.y;
  787.             DecLock(ax,ay);
  788.             char oox=ax>>2;
  789.             char ooy=ay>>2;
  790.             byte Kind=OBJ->Kind;
  791.             assert(ax==OBJ->x&&ay==OBJ->y);
  792.             OBJ->Direction=drrb[(ASK.dx+1)*3+ASK.dy+1];
  793.             TrMap[ay][ax]=0;
  794.             //LLock[ay][ax]=0;
  795.             assert(abs(ASK.dx)<2&&abs(ASK.dy)<2);
  796.             byte anx=ax+ASK.dx;
  797.             byte any=ay+ASK.dy;
  798.             IncLock(anx,any);
  799.             OBJ->x=anx;
  800.             OBJ->y=any;
  801.             char onx=anx>>2;
  802.             char ony=any>>2;
  803.             Mops[OBJ->y][OBJ->x]=OBJ->Index;
  804.             if(Mops[ay][ax]==OBJ->Index)Mops[ay][ax]=0xFFFF;
  805.             Ask[i].x=OBJ->x;
  806.             Ask[i].y=OBJ->y;
  807.             OBJ->Addx=-ASK.dx<<5;
  808.             OBJ->Addy=-ASK.dy<<5;
  809.             OBJ->LoadCurAnm(1);
  810.             OBJ->isMoving=true;
  811.             OBJ->StandTime=0;
  812.             //if(OBJ->Removed)OBJ->LineOffset+=3;
  813.             Ask[i].x=OBJ->x;
  814.             Ask[i].y=OBJ->y;
  815.             if(oox!=onx||ooy!=ony){
  816.                 Cell8x8* OldCell=&TCInf[OBJ->NNUM][ooy][oox];    
  817.                 Cell8x8* NewCell=&TCInf[OBJ->NNUM][ony][onx];
  818.                 OldCell->UnitsAmount[Kind]--;
  819.                 NewCell->UnitsAmount[Kind]++;
  820.             };
  821.         }else{
  822.             OBJ->StandTime++;
  823.             if(!(ASK.ReqID&0x8000)){
  824.                 byte ax=ASK.x+ASK.dx;
  825.                 byte ay=ASK.y+ASK.dy;
  826.                 int mopsa=Mops[ay][ax];
  827.                 if(mopsa!=0xFFFF){
  828.                     OneObject* OBJ2=Group[mopsa];
  829.                     //if(OBJ->StandTime>1)
  830.                         OBJ2->MoveFrom(OBJ->Direction);
  831.                 }else{;
  832.                     OBJ->FreeAsmLink();
  833.                     OBJ->LineOffset=0;
  834.                 };
  835.             };
  836.             OBJ->LoadAnimation(0,OBJ->AnmStandKind,0);
  837.             OBJ->LoadCurAnm(0);
  838.             OBJ->PathBroken=true;
  839.         };
  840.     };
  841. };
  842. void OneObject::MakeProcess(){
  843. };
  844. //Inline- Ωε∞αφΣ√ ∩ε±≥≡εσφΦ  Γφ≤≥≡σφφΦ⌡ Ωε∞αφΣ
  845. int Ofst;
  846. char* NowBuf;
  847. inline void ChkOfst(int size){
  848.     if(Ofst>=OneAsmSize-size-5-4){
  849.         char* NN=GetAsmBlock();
  850.         if(int(NN)){
  851.             NowBuf[Ofst]=7;
  852.             memcpy(&NowBuf[Ofst+1],&NN,4);
  853.             memcpy(&NowBuf[OneAsmSize-4],&NN,4);
  854.             NowBuf=NN;
  855.             Ofst=0;
  856.             memcpy(&NowBuf[OneAsmSize-4],&Ofst,4);
  857.         }else
  858.             NowBuf[Ofst]=0;
  859.     };
  860. };
  861. inline void cmSetXY(char x,char y){
  862.     ChkOfst(3);
  863.     assert(abs(x)<2&&abs(y)<2);
  864.     NowBuf[Ofst]=4;
  865.     NowBuf[Ofst+1]=x;
  866.     NowBuf[Ofst+2]=y;
  867.     Ofst+=3;
  868. };
  869. inline void cmSetXYDir(byte x,byte y,byte dir,byte n){
  870.     ChkOfst(4);
  871.     NowBuf[Ofst]=18;
  872.     NowBuf[Ofst+1]=x;
  873.     NowBuf[Ofst+2]=y;
  874.     NowBuf[Ofst+3]=(dir&7)|(n<<4);
  875.     Ofst+=4;
  876. };
  877. inline void cmSetXYDirX(byte x,byte y,char dx,char dy,byte n){
  878.     ChkOfst(4);
  879.     assert(dx<2&&dy<2);
  880.     byte dr=drr[(dx+1)*3+dy+1];
  881.     NowBuf[Ofst]=18;
  882.     NowBuf[Ofst+1]=x;
  883.     NowBuf[Ofst+2]=y;
  884.     NowBuf[Ofst+3]=(dr&7)|(n<<4);
  885.     Ofst+=4;
  886. };
  887.  
  888. inline void cmChkXY(byte x,byte y){
  889.     ChkOfst(3);
  890.     NowBuf[Ofst]=44;
  891.     NowBuf[Ofst+1]=x;
  892.     NowBuf[Ofst+2]=y;
  893.     Ofst+=3;
  894. };
  895. inline void cmSetDir(int dx,int dy){
  896.     if(dx==0&&dy==0)return;
  897.     byte dr=drr[(dx+1)*3+dy+1];
  898.     ChkOfst(2);
  899.     NowBuf[Ofst]=5;
  900.     NowBuf[Ofst+1]=dr;
  901.     Ofst+=2;
  902. };
  903. void cmSetDirD(byte dr){
  904.     ChkOfst(2);
  905.     NowBuf[Ofst]=5;
  906.     NowBuf[Ofst+1]=dr&7;
  907.     Ofst+=2;
  908. };
  909. inline void cmLoadAnm(byte stype,byte dtype,word kind){
  910.     ChkOfst(5);
  911.     NowBuf[Ofst]=6;
  912.     NowBuf[Ofst+1]=dtype;
  913.     NowBuf[Ofst+2]=stype;
  914.     NowBuf[Ofst+3]=byte(kind);
  915.     NowBuf[Ofst+4]=0;
  916.     Ofst+=5;
  917. };
  918. inline void cmPerfAnm(byte n){
  919.     ChkOfst(2);
  920.     NowBuf[Ofst]=8;
  921.     NowBuf[Ofst+1]=n;
  922.     Ofst+=2;
  923. };
  924. inline void cmRet(){
  925.     NowBuf[Ofst]=1;
  926.     Ofst+=1;
  927. };
  928. inline void cmDone(){
  929.     NowBuf[Ofst]=3;
  930.     Ofst+=1;
  931. };
  932. //╧σ≡σ∞σ±≥Φ≥ⁿ εß·σΩ≥ Γ ≥ε≈Ω≤ (x,y)
  933. typedef byte xxx[64];
  934. void COrd(Order1* ordr){
  935.     if(!int(ordr))return;
  936.     if((int(ordr)-int(OrdBuf))/sizeof Order1>=MaxOrdCount){
  937.         int RRRR=(int(ordr)-int(OrdBuf))/sizeof Order1;
  938.     };
  939. };
  940. byte circ[16];
  941. inline void FillCirc(int x,int y){
  942.     __asm{
  943.         xor        ebx,ebx
  944.         mov        bh,byte ptr y
  945.         //inc        bh
  946.         mov        bl,byte ptr x
  947.         //inc        bl
  948.         add        ebx,offset TrMap
  949.         mov        al,[ebx-256]
  950.         mov        circ[0],al
  951.         mov        al,[ebx-255]
  952.         mov        circ[1],al
  953.         mov        al,[ebx+1]
  954.         mov        circ[2],al
  955.         mov        al,[ebx+257]
  956.         mov        circ[3],al
  957.         mov        al,[ebx+256]
  958.         mov        circ[4],al
  959.         mov        al,[ebx+255]
  960.         mov        circ[5],al
  961.         mov        al,[ebx-1]
  962.         mov        circ[6],al
  963.         mov        al,[ebx-257]
  964.         mov        circ[7],al
  965.         mov        eax,dword ptr circ[0]
  966.         mov        dword ptr circ[8],eax
  967.         mov        eax,dword ptr circ[4]
  968.         mov        dword ptr circ[12],eax
  969.     }
  970. };
  971. void SendToLink(OneObject* OBJ);
  972. void OneObject::SendTo(int x2,int y2,int Prio){
  973. #define MaxP 160
  974.     if(Prio>=16)StandGround=false;
  975.     if(OnWater){
  976.         WSendTo(x2,y2,Prio);
  977.         return;
  978.     };
  979.     if(Media==2){
  980.         SendFlyTo(x2,y2,Prio);
  981.         return;
  982.     };
  983.     if(PrioryLevel>Prio)return;
  984.     if(!cpbMoving)return;
  985.     int x1=x2;
  986.     int y1=y2;
  987.     if(TrMap[y1][x1]){
  988.         //═α⌡εΣΦ∞ ßδΦµαΘ°≤■ φσταφ ≥≤■ ≥ε≈Ω≤
  989.         bool fnf=true;
  990.         for(int i=1;i<30;i++){
  991.             int z=i<<1;
  992.             for(int j=0;j<z;j++)
  993.                 if(!TrMap[y1-i][x1-i+j]){
  994.                     x1-=i-j;
  995.                     y1-=i;
  996.                     goto Em_Found;
  997.                 };
  998.             for(j=0;j<z;j++)
  999.                 if(!TrMap[y1-i+j][x1+i]){
  1000.                     y1-=i-j;
  1001.                     x1+=i;
  1002.                     goto Em_Found;
  1003.                 };
  1004.             for(j=0;j<z;j++)
  1005.                 if(!TrMap[y1+i][x1+i-j]){
  1006.                     y1+=i;
  1007.                     x1+=i-j;
  1008.                     goto Em_Found;
  1009.                 };
  1010.             for(j=0;j<z;j++)
  1011.                 if(!TrMap[y1+i-j][x1-i]){
  1012.                     y1+=i-j;
  1013.                     x1-=i;
  1014.                     goto Em_Found;
  1015.                 };
  1016.         };
  1017.     };
  1018. Em_Found:
  1019.     if(x==x1&&y==y1){
  1020.         if(int(LocalOrder)){
  1021.             if(!MemoryTime){
  1022.                 if(MemoryTime)MemoryTime--;
  1023.                 if(LocalOrder->OrderType==2){
  1024.                     Order1* Loc1=LocalOrder->NextOrder;
  1025.                     FreeOrdBlock(LocalOrder);
  1026.                     LocalOrder=Loc1;
  1027.                 };
  1028.             };
  1029.         };
  1030.         if(int(InLineCom))FreeAsmLink();
  1031.         //LoadAnimation(0,0,0);
  1032.         //LoadCurAnm(0);
  1033.         return;
  1034.     };
  1035.     //if(XYChanged)StandTime=0;
  1036.     MemoryTime=5;
  1037.     Order1* Or1=GetOrdBlock();
  1038.     if(!int(Or1))return;
  1039.     Or1->PrioryLevel=Prio&127;
  1040.     Or1->NextOrder=NULL;
  1041.     Or1->OrderType=2;
  1042.     Or1->OrderTime=0;
  1043.     Or1->DoLink=&SendToLink;
  1044.     Or1->info.MoveToXY.x=x1;
  1045.     Or1->info.MoveToXY.y=y1;
  1046.     Order1* LOR=LocalOrder;
  1047.     if(int(LOR)){
  1048.         //if(LOR->OrderType=2&&StandTime>5)TrMap[y][x]=1;
  1049.         ClearOrders();//reeOrdBlock(LocalOrder);
  1050.         if(LOR->OrderType!=2)StandTime=0; 
  1051.     }else StandTime=0;
  1052.     //StandTime=0;
  1053.     if(int(InLineCom)){
  1054.         FreeAsmLink();
  1055.         //LoadCurAnm(0);
  1056.     };
  1057.     LocalOrder=Or1;
  1058.     //OrderReport=NULL;
  1059.     //MessageKind=0;
  1060.     //Sender=0xFFFF;
  1061.     //if(Prio<128){
  1062.         //PushCmd(Index);
  1063.     //    return;
  1064.     //};
  1065.     //CreatePath(x1,y1);
  1066.     PrioryLevel=Prio&127;
  1067. }; 
  1068. void SendToLink(OneObject* OBJ){
  1069.     byte x1=OBJ->LocalOrder->info.MoveToXY.x;
  1070.     byte y1=OBJ->LocalOrder->info.MoveToXY.y;
  1071.     byte Prio=OBJ->LocalOrder->PrioryLevel;
  1072.     if(TrMap[y1][x1])OBJ->SendTo(x1,y1,Prio);else{
  1073.         byte x=OBJ->x;
  1074.         byte y=OBJ->y;
  1075.         if(x==x1&&y==y1){
  1076.             if(int(OBJ->LocalOrder)){
  1077.                 if(OBJ->MemoryTime)OBJ->MemoryTime--;
  1078.                 if(!OBJ->MemoryTime){
  1079.                     //if(OBJ->LocalOrder->OrderType==2){
  1080.                     Order1* Loc1=OBJ->LocalOrder->NextOrder;
  1081.                     OBJ->FreeOrdBlock(OBJ->LocalOrder);
  1082.                     OBJ->LocalOrder=Loc1;
  1083.                     //};
  1084.                 };
  1085.             };
  1086.             if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  1087.             //OBJ->LoadAnimation(0,0,0);
  1088.             //OBJ->LoadCurAnm(0);
  1089.             return;
  1090.         }else{
  1091.             if(int(OBJ->InLineCom)){
  1092.                 OBJ->FreeAsmLink();
  1093.                 //OBJ->LoadCurAnm(0);
  1094.             };
  1095.             OBJ->CreatePath(x1,y1);
  1096.             OBJ->MemoryTime=0;
  1097.         };
  1098.     };
  1099. };
  1100. //└≥αΩεΓα≥ⁿ εß·σΩ≥ ± ταΣαφφ√∞ ΦφΣσΩ±ε∞
  1101. void AttackObjLink(OneObject* OBJ);
  1102. void OneObject::AttackObj(word OID,int Prio){
  1103.     //assert(OID!=0xFFFF);
  1104.     if(!CheckAttAbility(this,OID))return;
  1105.     if(Prio>=16)StandGround=false;
  1106.     if(OnWater){
  1107.         WAttackObj(OID,Prio);
  1108.         return;
  1109.     };
  1110.     if(Media==2){
  1111.         FlyAttack(OID,Prio);
  1112.         return;
  1113.     };
  1114.     if(Prio<PrioryLevel/*&&!Attack*/)return;
  1115.     if(!Ready)return;
  1116.     if(!(cpbMoving||int(Weap)))return;
  1117.     ClearOrders();
  1118.     OneObject* OB=Group[OID];
  1119.     if(!int(OB)||OB->Sdoxlo)return;
  1120.     byte x1=OB->x;
  1121.     byte y1=OB->y;
  1122.     int sx=x1-x;
  1123.     int    sy=y1-y;
  1124.     int dx=abs(sx);
  1125.     int dy=abs(sy);
  1126.     int dst;
  1127.     if(dx>dy)dst=dx;
  1128.             else dst=dy;
  1129.     if((Attack&&dst>EnemyDist&&Prio<8)||(!Prio)&&dst>HREQRADIUS)return;
  1130.     if(Prio<16&&dst>MaxReplyDistance)return;
  1131.     Important=true;
  1132.     if(Attack){
  1133.         EnemyID=OID;
  1134.         EnemySN=OB->Serial;
  1135.         EnemyDist=dst;
  1136.         //SearchSupport(OID);
  1137.         return;
  1138.     };
  1139.     EnemyDist=dst;
  1140.     //SearchSupport(OID);
  1141.     if(NMask&OB->NMask)return;
  1142.     Order1* Or1=GetOrdBlock();
  1143.     assert(Or1);
  1144.     if(!int(Or1))return;
  1145.     Or1->PrioryLevel=Prio&127;
  1146.     Or1->NextOrder=LocalOrder;
  1147.     Or1->OrderType=3;//└≥αΩα
  1148.     Or1->OrderTime=0;
  1149.     Or1->DoLink=&AttackObjLink;
  1150.     Or1->info.MoveToObj.ObjIndex=OID;
  1151.     EnemyID=OID;
  1152.     EnemySN=OB->Serial;
  1153.     Attack=true;
  1154.     Order1* LOR=LocalOrder;
  1155.     if(int(InLineCom))FreeAsmLink();
  1156.     LocalOrder=Or1;
  1157.     //OrderReport=NULL;
  1158.     //MessageKind=0;
  1159.     //Sender=0xFFFF;
  1160.     PrioryLevel=Prio&127;
  1161.     if(CrowdRef)CrowdRef->AddToAttackQueue(OID);
  1162. };    
  1163. void AttackObjLink(OneObject* OBJ){
  1164.     word OID=OBJ->EnemyID;
  1165.     word OSN=OBJ->EnemySN;
  1166.     Order1* Or1;
  1167.     if(OID>8192){
  1168.         if(OBJ->InLineCom)OBJ->FreeAsmLink();
  1169.         Or1=OBJ->LocalOrder->NextOrder;
  1170.         OBJ->FreeOrdBlock(OBJ->LocalOrder);
  1171.         OBJ->LocalOrder=Or1;
  1172.         OBJ->Important=false;
  1173.         return;
  1174.     };
  1175.     OneObject* OB=Group[OID];
  1176.     OBJ->Important=true;
  1177.     //if(!OBJ->NeedNoHelp)OBJ->SearchSupport(OID);
  1178.     if((!int(OB))||OB->Sdoxlo||OB->NMask&OBJ->NMask||OSN!=OB->Serial){
  1179.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  1180.         if(int(OBJ->LocalOrder)){
  1181.             Or1=OBJ->LocalOrder->NextOrder;
  1182.             OBJ->FreeOrdBlock(OBJ->LocalOrder);
  1183.             OBJ->LocalOrder=Or1;
  1184.             OBJ->Important=false;
  1185.             return;
  1186.         };
  1187.     };
  1188.     byte x0=OB->x;
  1189.     byte y0=OB->y;
  1190.     byte olx=OB->Lx;
  1191.     byte oly=OB->Ly;
  1192.     byte xo=OBJ->x;
  1193.     byte yo=OBJ->y;
  1194.     if(xo<x0)xo=x0;else if(xo>=x0+olx)xo=x0+olx-1;
  1195.     if(yo<y0)yo=y0;else if(yo>=y0+oly)yo=y0+oly-1;
  1196.     int sx=xo-OBJ->x;
  1197.     int sy=yo-OBJ->y;
  1198.     int ssx=((xo-OBJ->x)<<5)-OBJ->wepX;
  1199.     int    ssy=((yo-OBJ->y)<<5)-OBJ->wepY;
  1200.     int dx=abs(sx);
  1201.     int dy=abs(sy);
  1202.     int dst;
  1203.     Visuals* VS=OBJ->Ref.Visual;
  1204.     if(dx>dy)dst=dx;
  1205.             else dst=dy;
  1206.     OBJ->EnemyDist=dst;
  1207.     if(dst<2&&OBJ->cpbMoving&&!OBJ->delay){
  1208.         OBJ->Direction=drr[(sx+1)*3+sy+1];
  1209.         OBJ->LoadAnimation(2,2,0);
  1210.         OBJ->LoadCurAnm(2);
  1211.         int Midm=(VS->info.Basic.MinDamage*OBJ->xForce)>>4;
  1212.         int Madm=(VS->info.Basic.MaxDamage*OBJ->xForce)>>4;
  1213.         //Dam=(Dam*OBJ->xForce)>>4;
  1214.         //if(OB->Life>Dam)OB->Life-=Dam;else OB->Life=0;
  1215.         OB->MakeDamage(Madm,Midm,OBJ);
  1216.         AddWarEffect(OB->x,OB->y,VS->HitSound);
  1217.         OBJ->isMoving=false;
  1218.         OBJ->delay=OBJ->MaxDelay;
  1219.         //TrMap[OBJ->y][OBJ->x]=1;
  1220.     }else{ 
  1221.         if(OBJ->delay&&OBJ->Use_AI&&VS->CanFear&&OBJ->cpbMoving&&!OBJ->StandGround){
  1222.             if(sx>0)sx=1;
  1223.             if(sy>0)sy=1;
  1224.             if(sx<0)sx=-1;
  1225.             if(sy<0)sy=-1;
  1226.             if(!TrMap[OBJ->y-sy][OBJ->x-sx]){
  1227.                 OBJ->CreatePath(OBJ->x-sx,OBJ->y-sy);
  1228.                 return;
  1229.             };
  1230.             if(!TrMap[OBJ->y][OBJ->x-sx]){
  1231.                 OBJ->CreatePath(OBJ->x-sx,OBJ->y);
  1232.                 return;
  1233.             };
  1234.             if(!TrMap[OBJ->y-sy][OBJ->x]){
  1235.                 OBJ->CreatePath(OBJ->x,OBJ->y-sy);
  1236.                 return;
  1237.             };
  1238.             return;
  1239.         };
  1240.         if(dst<VS->info.Basic.AttackRange&&dst>VS->DangerZone){
  1241.             if(OBJ->Weap&&!OBJ->delay){
  1242.                 OBJ->isMoving=false;
  1243.                 OBJ->delay=OBJ->Ref.General->WepDelay;
  1244.                 if(OBJ->cpbMoving){
  1245.                     OBJ->LoadAnimation(2,2,0);
  1246.                     OBJ->LoadCurAnm(2);
  1247.                     //TrMap[OBJ->y][OBJ->x]=1;
  1248.                     OBJ->Direction=
  1249.                         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);
  1250.                     //OBJ->MakeDamage(0,OBJ->Ref.General->LifeShotLost,OB);
  1251.                 }else{
  1252.                     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);
  1253.                     //OBJ->MakeDamage(0,OBJ->Ref.General->LifeShotLost,OB);
  1254.                 };
  1255.             };
  1256.         }else
  1257.         if(OBJ->cpbMoving&&!OBJ->StandGround)OBJ->CreateSimplePath(xo,yo);
  1258.     };
  1259. };
  1260. //Complex └≥αΩεΓα≥ⁿ εß·σΩ≥ ± ταΣαφφ√∞ ΦφΣσΩ±ε∞
  1261. void ComplexAttackLink(OneObject* OBJ);
  1262. void OneObject::ComplexAttack(word OID,byte wep,int Prio){
  1263.     if(Prio>=16)StandGround=false;
  1264.     if(OnWater){
  1265.         WAttackObj(OID,Prio);
  1266.         return;
  1267.     };
  1268.     if(Media==2){
  1269.         FlyAttack(OID,Prio);
  1270.         return;
  1271.     };
  1272.     if(Ref.General->NWeap<=wep)return;
  1273.     if(Prio<PrioryLevel&&!Attack)return;
  1274.     if(!Ready)return;
  1275.     if(!(cpbMoving||int(Weap)))return;
  1276.     OneObject* OB=Group[OID];
  1277.     if(!int(OB)||OB->Sdoxlo)return;
  1278.     if(NMask&OB->NMask)return;
  1279.     Order1* Or1=GetOrdBlock();
  1280.     if(!int(Or1))return;
  1281.     Or1->PrioryLevel=Prio&127;
  1282.     Or1->NextOrder=LocalOrder;
  1283.     Or1->OrderType=34;//└≥αΩα
  1284.     Or1->OrderTime=0;
  1285.     Or1->DoLink=&ComplexAttackLink;
  1286.     Or1->info.MoveToObj.ObjIndex=OID;
  1287.     Or1->info.MoveToObj.wep=wep;
  1288.     Order1* LOR=LocalOrder;
  1289.     if(int(InLineCom))FreeAsmLink();
  1290.     LocalOrder=Or1;
  1291.     //OrderReport=NULL;
  1292.     //MessageKind=0;
  1293.     //Sender=0xFFFF;
  1294.     PrioryLevel=Prio&127;
  1295. };    
  1296. void ComplexAttackLink(OneObject* OBJ){
  1297.     word OID=OBJ->LocalOrder->info.MoveToObj.ObjIndex;
  1298.     byte wep=OBJ->LocalOrder->info.MoveToObj.wep;
  1299.     OneObject* OB=Group[OID];
  1300.     OBJ->Important=true;
  1301.     //if(!OBJ->NeedNoHelp)OBJ->SearchSupport(OID);
  1302.     Order1* Or1;
  1303.     if((!int(OB))||OB->Sdoxlo||OB->NMask&OBJ->NMask){
  1304.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  1305.         if(int(OBJ->LocalOrder)){
  1306.             Or1=OBJ->LocalOrder->NextOrder;
  1307.             OBJ->FreeOrdBlock(OBJ->LocalOrder);
  1308.             OBJ->LocalOrder=Or1;
  1309.             OBJ->Important=false;
  1310.             return;
  1311.         };
  1312.     };
  1313.     byte x0=OB->x;
  1314.     byte y0=OB->y;
  1315.     byte olx=OB->Lx;
  1316.     byte oly=OB->Ly;
  1317.     byte xo=OBJ->x;
  1318.     byte yo=OBJ->y;
  1319.     if(xo<x0)xo=x0;else if(xo>=x0+olx)xo=x0+olx-1;
  1320.     if(yo<y0)yo=y0;else if(yo>=y0+oly)yo=y0+oly-1;
  1321.     int sx=xo-OBJ->x;
  1322.     int sy=yo-OBJ->y;
  1323.     int ssx=((xo-OBJ->x)<<5)-OBJ->wepX;
  1324.     int    ssy=((yo-OBJ->y)<<5)-OBJ->wepY;
  1325.     int dx=abs(sx);
  1326.     int dy=abs(sy);
  1327.     int dst;
  1328.     if(dx>dy)dst=dx;
  1329.             else dst=dy;
  1330.     OBJ->EnemyDist=dst;
  1331.     Visuals* VS=OBJ->Ref.Visual;
  1332.     SWPAR* SWX=&OBJ->Nat->SWP[VS->SWPIndex[wep]];
  1333.     if(dst<2&&OBJ->cpbMoving&&!OBJ->delay){
  1334.         OBJ->Direction=drr[(sx+1)*3+sy+1];
  1335.         OBJ->LoadAnimation(2,2,0);
  1336.         OBJ->LoadCurAnm(2);
  1337.         int Midm=OBJ->Ref.Visual->info.Basic.MinDamage;
  1338.         int Madm=OBJ->Ref.Visual->info.Basic.MaxDamage;
  1339.         int Dam=(((tmtmt&3)*(Madm-Midm))>>2)+Midm;
  1340.         //Dam=(Dam*OBJ->xForce)>>4;
  1341.         //if(OB->Life>Dam)OB->Life-=Dam;else OB->Life=0;
  1342.         OB->MakeDamage(Madm,Midm,OBJ);
  1343.         OBJ->isMoving=false;
  1344.         OBJ->delay=OBJ->MaxDelay;
  1345.     }else{ 
  1346.         Visuals* VS=OBJ->Ref.Visual;
  1347.         if(dst<SWX->Range&&dst>VS->DangerZone){
  1348.             if(OBJ->Weap&&!OBJ->delay){
  1349.                 OBJ->isMoving=false;
  1350.                 OBJ->delay=OBJ->MaxDelay;
  1351.                 if(OBJ->cpbMoving){
  1352.                     OBJ->LoadAnimation(2,2,0);
  1353.                     OBJ->LoadCurAnm(2);
  1354.                     if(SWX->Fly)
  1355.                         OBJ->Direction=
  1356.                             //CreateExObjR(OBJ->Ref.General->MWeap[wep],((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,ssx,ssy,64,OBJ->NMask,OBJ,SWX->Range);
  1357.                             CreateUniExObj(OBJ->Ref.General->MWeap[wep],((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);
  1358.                     else
  1359.                         OBJ->Direction=
  1360.                         //CreateExObjR(OBJ->Ref.General->MWeap[wep]->NextWeapon,((OB->x<<5)+512)<<2,((OB->y<<5)+512)<<2,ssx,ssy,0,OBJ->NMask,OBJ,SWX->Range);
  1361.                         CreateUniExObj(OBJ->Ref.General->MWeap[wep]->NextWeapon,((OB->x<<5)+16)<<2,((OB->y<<5)+16)<<2,0,OBJ->NMask,OBJ,255,255,0xFFFF);
  1362.                     //OBJ->MakeDamage(0,OBJ->Ref.General->LifeShotLost,OB);
  1363.                 }else{
  1364.                     if(SWX->Fly)CreateUniExObj(OBJ->Ref.General->MWeap[wep],((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);
  1365.                     else CreateUniExObj(OBJ->Ref.General->MWeap[wep]->NextWeapon,((OB->x<<5)+16)<<2,((OB->y<<5)+16)<<2,0,OBJ->NMask,OBJ,255,255,0xFFFF);
  1366.                     //OBJ->MakeDamage(0,OBJ->Ref.General->LifeShotLost,OB);
  1367.                 };
  1368.             };
  1369.             Order1* OR1=OBJ->LocalOrder;
  1370.             OBJ->LocalOrder=OR1->NextOrder;
  1371.             OBJ->FreeOrdBlock(OR1);
  1372.         }else
  1373.         if(OBJ->cpbMoving&&!OBJ->StandGround)OBJ->CreatePath(xo,yo);
  1374.     };
  1375. };
  1376. //└≥αΩεΓα≥ⁿ point
  1377. void AttackPointLink(OneObject* OBJ);
  1378. void OneObject::AttackPoint(byte x,byte y,byte wep,int Prio){
  1379.     if(Prio>=16)StandGround=false;
  1380.     if(OnWater){
  1381.         //WAttackObj(OID,Prio);
  1382.         return;
  1383.     };
  1384.     if(Media==2){
  1385.         //FlyAttack(OID,Prio);
  1386.         return;
  1387.     };
  1388.     if(Ref.General->NWeap<=wep)return;
  1389.     if(Prio<PrioryLevel)return;
  1390.     if(!Ready)return;
  1391.     if(!(cpbMoving||int(Weap)))return;
  1392.     Order1* Or1=GetOrdBlock();
  1393.     if(!int(Or1))return;
  1394.     Or1->PrioryLevel=Prio&127;
  1395.     Or1->NextOrder=LocalOrder;
  1396.     Or1->OrderType=33;//└≥αΩα
  1397.     Or1->OrderTime=0;
  1398.     Or1->DoLink=&AttackPointLink;
  1399.     Or1->info.AttackXY.x=x;
  1400.     Or1->info.AttackXY.y=y;
  1401.     Or1->info.AttackXY.wep=wep;
  1402.     //EnemyID=OID;
  1403.     Order1* LOR=LocalOrder;
  1404.     if(int(InLineCom))FreeAsmLink();
  1405.     LocalOrder=Or1;
  1406.     //OrderReport=NULL;
  1407.     //MessageKind=0;
  1408.     //Sender=0xFFFF;
  1409.     PrioryLevel=Prio&127;
  1410. };    
  1411. void AttackPointLink(OneObject* OBJ){
  1412.     int xd=OBJ->LocalOrder->info.AttackXY.x;
  1413.     int yd=OBJ->LocalOrder->info.AttackXY.y;
  1414.     byte wep=OBJ->LocalOrder->info.AttackXY.wep;
  1415.     //word OID=OBJ->EnemyID;
  1416.     //OneObject* OB=Group[OID];
  1417.     OBJ->Important=true;
  1418.     //if(!OBJ->NeedNoHelp)OBJ->SearchSupport(OID);
  1419.     int ssx=((xd-OBJ->x)<<5)-OBJ->wepX;
  1420.     int    ssy=((yd-OBJ->y)<<5)-OBJ->wepY;
  1421.     int sx=xd-OBJ->x;
  1422.     int sy=yd-OBJ->y;
  1423.     int dx=abs(sx);
  1424.     int dy=abs(sy);
  1425.     int dst;
  1426.     if(dx>dy)dst=dx;
  1427.             else dst=dy;
  1428.     OBJ->EnemyDist=dst;
  1429.     Visuals* VS=OBJ->Ref.Visual;
  1430.     SWPAR* SWX=&OBJ->Nat->SWP[VS->SWPIndex[wep]];
  1431.     if(dst<SWX->Range&&dst>VS->DangerZone){
  1432.         if(wep<OBJ->Ref.General->NWeap){
  1433.             OBJ->isMoving=false;
  1434.             if(OBJ->cpbMoving){
  1435.                 OBJ->LoadAnimation(2,2,0);
  1436.                 OBJ->LoadCurAnm(2);
  1437.                 if(SWX->Fly)
  1438.                     OBJ->Direction=
  1439.                         CreateUniExObj(OBJ->Ref.General->MWeap[wep],((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1440.                         //CreateExObjDPointR(OBJ->Ref.General->MWeap[wep],((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,ssx,ssy,64,OBJ->NMask,OBJ,xd,yd,SWX->Range);
  1441.                 else 
  1442.                     OBJ->Direction=
  1443.                         CreateUniExObj(OBJ->Ref.General->MWeap[wep]->NextWeapon,((xd<<5)+16)<<2,((yd<<5)+16)<<2,0,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1444.                         //CreateExObjDPointR(OBJ->Ref.General->MWeap[wep]->NextWeapon,((xd<<5)+16)<<2,((yd<<5)+16)<<2,ssx,ssy,64,OBJ->NMask,OBJ,xd,yd,SWX->Range);
  1445.                 //OBJ->MakeDamage(OBJ->Ref.General->LifeShotLost,OB);
  1446.             }else{
  1447.                 if(SWX->Fly)CreateUniExObj(OBJ->Ref.General->MWeap[wep],((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1448.                 else CreateUniExObj(OBJ->Ref.General->MWeap[wep]->NextWeapon,((xd<<5)+16)<<2,((yd<<5)+16)<<2,0,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1449.                 //CreateExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,ssx,ssy,64,OBJ->NMask,OBJ);
  1450.                 //OBJ->MakeDamage(OBJ->Ref.General->LifeShotLost,OB);
  1451.             };
  1452.             Order1* Loc1=OBJ->LocalOrder;
  1453.             OBJ->LocalOrder=Loc1->NextOrder;
  1454.             OBJ->FreeOrdBlock(Loc1);
  1455.         };
  1456.     }else
  1457.         if(OBJ->cpbMoving&&!OBJ->StandGround)OBJ->CreatePath(xd,yd);
  1458.     
  1459. };
  1460. //└≥αΩεΓα≥ⁿ point
  1461. void ContinueAttackPointLink(OneObject* OBJ);
  1462. void OneObject::ContinueAttackPoint(byte x,byte y,int Prio){
  1463.     if(Prio>=16)StandGround=false;
  1464.     if(OnWater){
  1465.         //WAttackObj(OID,Prio);
  1466.         return;
  1467.     };
  1468.     if(Media==2){
  1469.         //FlyAttack(OID,Prio);
  1470.         return;
  1471.     };
  1472.     if(Ref.Visual->info.Basic.AttackRange<2||!Weap)return;
  1473.     
  1474.     if(Prio<PrioryLevel)return;
  1475.     if(!Ready)return;
  1476.     if(!(cpbMoving||int(Weap)))return;
  1477.     Order1* Or1=GetOrdBlock();
  1478.     if(!int(Or1))return;
  1479.     ClearOrders();
  1480.     Or1->PrioryLevel=Prio&127;
  1481.     Or1->NextOrder=LocalOrder;
  1482.     Or1->OrderType=34;//└≥αΩα
  1483.     Or1->OrderTime=0;
  1484.     Or1->DoLink=&ContinueAttackPointLink;
  1485.     Or1->info.AttackXY.x=x;
  1486.     Or1->info.AttackXY.y=y;
  1487.     //EnemyID=OID;
  1488.     Order1* LOR=LocalOrder;
  1489.     if(int(InLineCom))FreeAsmLink();
  1490.     LocalOrder=Or1;
  1491.     //OrderReport=NULL;
  1492.     //MessageKind=0;
  1493.     //Sender=0xFFFF;
  1494.     PrioryLevel=Prio&127;
  1495. };    
  1496. void ContinueAttackPointLink(OneObject* OBJ){
  1497.     int xd=OBJ->LocalOrder->info.AttackXY.x;
  1498.     int yd=OBJ->LocalOrder->info.AttackXY.y;
  1499.     //word OID=OBJ->EnemyID;
  1500.     //OneObject* OB=Group[OID];
  1501.     OBJ->Important=true;
  1502.     //if(!OBJ->NeedNoHelp)OBJ->SearchSupport(OID);
  1503.     int ssx=((xd-OBJ->x)<<5)-OBJ->wepX;
  1504.     int    ssy=((yd-OBJ->y)<<5)-OBJ->wepY;
  1505.     int sx=xd-OBJ->x;
  1506.     int sy=yd-OBJ->y;
  1507.     int dx=abs(sx);
  1508.     int dy=abs(sy);
  1509.     int dst;
  1510.     if(dx>dy)dst=dx;
  1511.             else dst=dy;
  1512.     OBJ->EnemyDist=dst;
  1513.     Visuals* VS=OBJ->Ref.Visual;
  1514.     if(dst<VS->info.Basic.AttackRange&&dst>VS->DangerZone){
  1515.         if(!OBJ->delay){
  1516.             OBJ->delay=OBJ->Ref.General->WepDelay;
  1517.             OBJ->isMoving=false;
  1518.             if(OBJ->cpbMoving){
  1519.                 OBJ->LoadAnimation(2,2,0);
  1520.                 OBJ->LoadCurAnm(2);
  1521.                 OBJ->Direction=
  1522.                     CreateUniExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1523.             }else{
  1524.                 CreateUniExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1525.             };
  1526.         };
  1527.     }else
  1528.         if(OBJ->cpbMoving&&!OBJ->StandGround)OBJ->CreatePath(xd,yd);
  1529.     
  1530. };
  1531. //└≥αΩεΓα≥ⁿ ±≥σφ≤
  1532. void ContinueAttackWallLink(OneObject* OBJ);
  1533. void OneObject::ContinueAttackWall(byte x,byte y,int Prio){
  1534.     if(Prio>=16)StandGround=false;
  1535.     if(OnWater){
  1536.         //WAttackObj(OID,Prio);
  1537.         return;
  1538.     };
  1539.     if(Media==2){
  1540.         //FlyAttack(OID,Prio);
  1541.         return;
  1542.     };
  1543.     if(Ref.Visual->info.Basic.AttackRange<2||!Weap)return;
  1544.     
  1545.     if(Prio<PrioryLevel)return;
  1546.     if(!Ready)return;
  1547.     if(!(cpbMoving||int(Weap)))return;
  1548.     Order1* Or1=GetOrdBlock();
  1549.     if(!int(Or1))return;
  1550.     ClearOrders();
  1551.     Or1->PrioryLevel=Prio&127;
  1552.     Or1->NextOrder=LocalOrder;
  1553.     Or1->OrderType=34;//└≥αΩα
  1554.     Or1->OrderTime=0;
  1555.     Or1->DoLink=&ContinueAttackWallLink;
  1556.     Or1->info.AttackXY.x=x;
  1557.     Or1->info.AttackXY.y=y;
  1558.     //EnemyID=OID;
  1559.     Order1* LOR=LocalOrder;
  1560.     if(int(InLineCom))FreeAsmLink();
  1561.     LocalOrder=Or1;
  1562.     //OrderReport=NULL;
  1563.     //MessageKind=0;
  1564.     //Sender=0xFFFF;
  1565.     PrioryLevel=Prio&127;
  1566. };    
  1567. void ContinueAttackWallLink(OneObject* OBJ){
  1568.     int xd=OBJ->LocalOrder->info.AttackXY.x;
  1569.     int yd=OBJ->LocalOrder->info.AttackXY.y;
  1570.     //word OID=OBJ->EnemyID;
  1571.     //OneObject* OB=Group[OID];
  1572.     OBJ->Important=true;
  1573.     //if(!OBJ->NeedNoHelp)OBJ->SearchSupport(OID);
  1574.     word LNK=Links[yd][xd];
  1575.     if(LNK==0xFFFF){
  1576.         if(Links[yd][xd-1]!=0xFFFF)xd--;
  1577.         else if(Links[yd-1][xd]!=0xFFFF)yd--;
  1578.         else if(Links[yd][xd+1]!=0xFFFF)xd++;
  1579.         else if(Links[yd+1][xd]!=0xFFFF)yd++;
  1580.     };
  1581.     if(Links[yd][xd]==0xFFFF){
  1582.         OBJ->ClearOrders();
  1583.         return;
  1584.     };
  1585.     OBJ->LocalOrder->info.AttackXY.x=xd;
  1586.     OBJ->LocalOrder->info.AttackXY.y=yd;
  1587.     int ssx=((xd-OBJ->x)<<5)-OBJ->wepX;
  1588.     int    ssy=((yd-OBJ->y)<<5)-OBJ->wepY;
  1589.     int sx=xd-OBJ->x;
  1590.     int sy=yd-OBJ->y;
  1591.     int dx=abs(sx);
  1592.     int dy=abs(sy);
  1593.     int dst;
  1594.     if(dx>dy)dst=dx;
  1595.             else dst=dy;
  1596.     OBJ->EnemyDist=dst;
  1597.     Visuals* VS=OBJ->Ref.Visual;
  1598.     if(dst<VS->info.Basic.AttackRange&&dst>VS->DangerZone){
  1599.         if(!OBJ->delay){
  1600.             OBJ->delay=OBJ->Ref.General->WepDelay;
  1601.             OBJ->isMoving=false;
  1602.             if(OBJ->cpbMoving){
  1603.                 OBJ->LoadAnimation(2,2,0);
  1604.                 OBJ->LoadCurAnm(2);
  1605.                 OBJ->Direction=
  1606.                     CreateUniExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1607.             }else{
  1608.                 CreateUniExObj(OBJ->Weap,((OBJ->x<<5)+OBJ->wepX)<<2,((OBJ->y<<5)+OBJ->wepY)<<2,OBJ->Ref.General->WepSpeed,OBJ->NMask,OBJ,xd,yd,0xFFFF);
  1609.             };
  1610.         };
  1611.     }else
  1612.         if(OBJ->cpbMoving&&!OBJ->StandGround)OBJ->CreatePath(xd,yd);
  1613.     
  1614. };
  1615. //╧≡ε÷σΣ≤≡√ ε∩≥Φ∞Φτα÷ΦΦ ≤µσ ±πσφσ≡Φ≡εΓαφφεπε ∩≤≥Φ
  1616. //1. ╧≡ε±≥σΘ°α  ε∩≥Φ∞Φτα÷Φ -αφαδΦτ ±α∞ε∩σ≡σ±σ≈σφΦ  
  1617. //╚±∩εδⁿτ≤σ≥± ,ΩεπΣα ±εΓ±σ∞ ∞αδε Γ≡σ∞σφΦ(not used now)
  1618. byte xx[MaxP+160];
  1619. byte yy[MaxP+160];
  1620. int Optima1(int Npt){
  1621.     //╤ετΣασ∞ ±δσΣ φα Ωα≡≥σ
  1622. //    return Npt;
  1623.     if(!Npt)return 0;
  1624.     int NN;
  1625.     __asm{
  1626.         mov        eax,SIndex
  1627.         xor        ebx,ebx
  1628.         xor        ecx,ecx
  1629.         xor        esi,esi
  1630.         xor        edi,edi
  1631.         mov        esi,Npt
  1632. F_begin:
  1633.         mov        dx,word ptr xx[edi]
  1634.         mov        bx,word ptr yy[edi]
  1635.         mov        ch,bl
  1636.         mov        cl,dl
  1637.         mov        byte ptr [xi+ecx],dh
  1638.         mov        byte ptr [yi+ecx],bh
  1639.         inc        edi
  1640.         dec        esi
  1641.         jnz        F_Begin
  1642.         mov        byte ptr[xi+ecx],0//end of array
  1643.         //╥σ∩σ≡ⁿ ∩≤≥ⁿ πε≥εΓ, ε±≥αδε±ⁿ σπε ≥εδⁿΩε ±εß≡α≥ⁿ ∩ε ÷σ∩ε≈Ωσ
  1644.         mov        bl,byte ptr [xx]
  1645.         mov        bh,byte ptr [yy]
  1646.         xor        eax,eax
  1647. F_Lp1:
  1648.         mov        byte ptr [xx+eax],bl
  1649.         mov        byte ptr [yy+eax],bh
  1650.         mov        dl,byte ptr [xi+ebx]
  1651.         mov        dh,byte ptr [yi+ebx]
  1652.         mov        bx,dx
  1653.         inc        eax
  1654.         or        bl,bl
  1655.         jnz        F_Lp1
  1656.         mov        NN,eax
  1657.     };
  1658.     return NN;
  1659. };
  1660. bool ChkStright(int x0,int y0,int x1,int y1){
  1661.     int dx,dy,x,y;
  1662.     x=x0;y=y0;
  1663.     do{
  1664.         dx=x1-x;
  1665.         dy=y1-y;
  1666.         if(dx>1)dx=1;
  1667.         if(dx<-1)dx=-1;
  1668.         if(dy>1)dy=1;
  1669.         if(dy<-1)dy=-1;
  1670.         if(TrMap[y+dy][x+dx])return false;
  1671.         x+=dx;
  1672.         y+=dy;
  1673.     }while(x!=x1&&y!=y1);
  1674.     return true;
  1675. };
  1676. void OneObject::CreatePath(int x1,int y1){
  1677.     if(CPdestX==x1&&CPdestY==y1){
  1678.         if(PathX){
  1679.             if(CurIPoint<NIPoints){
  1680.                 byte cx=PathX[CurIPoint];
  1681.                 byte cy=PathY[CurIPoint];
  1682.                 int dis=DistTo(cx,cy);
  1683.                 if(dis<2)CurIPoint++;
  1684.                 //else if(dis<4&&ChkStright(x,y,cx,cy))CurIPoint++;
  1685.                 if(CurIPoint<NIPoints){
  1686.                     CreateSimplePath(PathX[CurIPoint],PathY[CurIPoint]);
  1687.                 }else{
  1688.                     int xx1=x;
  1689.                     int yy1=y;
  1690.                     x=cx;
  1691.                     y=cy;
  1692.                     CreatePrePath(x1,y1);
  1693.                     x=xx1;
  1694.                     y=yy1;
  1695.                 };
  1696.             };
  1697.         }else CreateSimplePath(x1,y1);
  1698.     }else{
  1699.         CreatePrePath(x1,y1);
  1700.     };
  1701.     CPdestX=x1;
  1702.     CPdestY=y1;
  1703. };
  1704. void OneObject::CreateSimplePath(int x1,int y1){
  1705.     PathAsks++;
  1706.     TrMap[y][x]=0;
  1707.     int sdx=x1-x;
  1708.     int    sdy=y1-y;
  1709.     int    Cum=0;
  1710.     int Pps=0;
  1711.     int sx=sdx;
  1712.     if(sx>1)sx=1;else
  1713.     if(sx<-1)sx=-1;
  1714.     int sy=sdy;
  1715.     if(sy>1)sy=1;else 
  1716.     if(sy<-1)sy=-1;
  1717.     int dx=abs(sdx);
  1718.     int dy=abs(sdy);
  1719.     int    Mdx=dx;
  1720.     int    Mdy=dy;
  1721.     int    Mx=x;
  1722.     int    My=y;
  1723.     int    xx1=x;
  1724.     int yy1=y;
  1725.     int rx=sx;
  1726.     int ry=sy;
  1727.     //if(dx>dy)ry=0;
  1728.     //if(dy>dx)rx=0;
  1729.     if(!TrMap[y+ry][x+rx]){
  1730.         LoadAnimation(1,AnmGoKind,0);
  1731.         AddAsk(Index,x,y,rx,ry);
  1732.         return;
  1733.     };
  1734.     //±εσΣΦφ σ∞ δΦφΦσΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■ ≥ε≈ΩΦ. 
  1735.     //╬∩≥Φ∞Φτα÷Φ  ≥εδⁿΩε ∩ε ±Ωε≡ε±≥Φ
  1736.     __asm{
  1737.         mov        ax,word ptr Mdx
  1738.         mov        bx,word ptr Mdy
  1739.         xor        edx,edx  //Pps
  1740.         xor        ecx,ecx  //Cum
  1741.         mov        si,word ptr Mx
  1742.         mov        di,word ptr My
  1743.         cmp        bx,ax
  1744.         jae        Lp5xx
  1745.         //dx>dy
  1746.         mov        word ptr[xx+edx],si
  1747.         mov        word ptr[yy+edx],di
  1748.         inc        edx
  1749.         or        ax,ax
  1750.         jz        LoopsEnd
  1751.         cmp        sy,0
  1752.         jl        Lp3xx
  1753.         cmp        sx,0
  1754.         jl        Lp2begin
  1755.         //dx>dy,sx>0,sy>0
  1756. Lp1begin:
  1757.         inc        si    //x++
  1758.         add        cx,bx
  1759.         cmp        cx,word ptr Mdx
  1760.         jb        Lp1_1
  1761.         sub        cx,word ptr Mdx
  1762.         inc        di  //y++
  1763. Lp1_1:
  1764.         mov        word ptr[xx+edx],si
  1765.         mov        word ptr[yy+edx],di
  1766.         inc        edx
  1767.         dec        ax
  1768.         jnz        Lp1begin
  1769.         jmp        LoopsEnd
  1770. Lp2begin: //dx>dy,sx<0,sy>0
  1771.         dec        si    //x--
  1772.         add        cx,bx
  1773.         cmp        cx,word ptr Mdx
  1774.         jb        Lp2_1
  1775.         sub        cx,word ptr Mdx
  1776.         inc        di //y++
  1777. Lp2_1:
  1778.         mov        word ptr[xx+edx],si
  1779.         mov        word ptr[yy+edx],di
  1780.         inc        edx
  1781.         dec        ax
  1782.         jnz        Lp2begin
  1783.         jmp        LoopsEnd
  1784. Lp3xx:    //dy<0
  1785.         cmp        sx,0
  1786.         jl        Lp4begin
  1787. Lp3begin: //dx>dy,sx>0,sy<0
  1788.         inc        si    //x++
  1789.         add        cx,bx
  1790.         cmp        cx,word ptr Mdx
  1791.         jb        Lp3_1
  1792.         sub        cx,word ptr Mdx
  1793.         dec        di //y--
  1794. Lp3_1:
  1795.         mov        word ptr[xx+edx],si
  1796.         mov        word ptr[yy+edx],di
  1797.         inc        edx
  1798.         dec        ax
  1799.         jnz        Lp3begin
  1800.         jmp        LoopsEnd
  1801. Lp4begin: //dx>dy,sx<0,sy<0
  1802.         dec        si    //x--
  1803.         add        cx,bx
  1804.         cmp        cx,word ptr Mdx
  1805.         jb        Lp4_1
  1806.         sub        cx,word ptr Mdx
  1807.         dec        di //y--
  1808. Lp4_1:
  1809.         mov        word ptr[xx+edx],si
  1810.         mov        word ptr[yy+edx],di
  1811.         inc        edx
  1812.         dec        ax
  1813.         jnz        Lp4begin
  1814.         jmp        LoopsEnd
  1815. Lp5xx:    //dx<dy
  1816.         mov        word ptr[xx+edx],si
  1817.         mov        word ptr[yy+edx],di
  1818.         inc        edx
  1819.         or        bx,bx
  1820.         jz        LoopsEnd
  1821.         cmp        sx,0
  1822.         jl        Lp7xx
  1823.         cmp        sy,0
  1824.         jl        Lp6begin
  1825. Lp5Begin:
  1826.         inc        di    //y++
  1827.         add        cx,ax
  1828.         cmp        cx,word ptr dy
  1829.         jb        Lp5_1
  1830.         sub        cx,word ptr dy
  1831.         inc        si    //x++
  1832. Lp5_1:
  1833.         mov        word ptr[xx+edx],si
  1834.         mov        word ptr[yy+edx],di
  1835.         inc        edx
  1836.         dec        bx
  1837.         jnz        Lp5begin
  1838.         jmp        LoopsEnd
  1839. Lp6Begin://sx>0,sy<0
  1840.         dec        di    //y++
  1841.         add        cx,ax
  1842.         cmp        cx,word ptr dy
  1843.         jb        Lp6_1
  1844.         sub        cx,word ptr dy
  1845.         inc        si    //x++
  1846. Lp6_1:
  1847.         mov        word ptr[xx+edx],si
  1848.         mov        word ptr[yy+edx],di
  1849.         inc        edx
  1850.         dec        bx
  1851.         jnz        Lp6begin
  1852.         jmp        LoopsEnd
  1853. Lp7xx:    //dx<0
  1854.         cmp        sy,0
  1855.         jl        Lp8begin
  1856. Lp7Begin://dx<0,dy>0
  1857.         inc        di    //y++
  1858.         add        cx,ax
  1859.         cmp        cx,word ptr dy
  1860.         jb        Lp7_1
  1861.         sub        cx,word ptr dy
  1862.         dec        si    //x--
  1863. Lp7_1:
  1864.         mov        word ptr[xx+edx],si
  1865.         mov        word ptr[yy+edx],di
  1866.         inc        edx
  1867.         dec        bx
  1868.         jnz        Lp7begin
  1869.         jmp        LoopsEnd
  1870. Lp8Begin://dx<0,dy<0
  1871.         dec        di    //y--
  1872.         add        cx,ax
  1873.         cmp        cx,word ptr dy
  1874.         jb        Lp8_1
  1875.         sub        cx,word ptr dy
  1876.         dec        si    //x--
  1877. Lp8_1:
  1878.         mov        word ptr[xx+edx],si
  1879.         mov        word ptr[yy+edx],di
  1880.         inc        edx
  1881.         dec        bx
  1882.         jnz        Lp8begin
  1883. loopsEnd:
  1884.         //shr        edx,1
  1885.         mov        Pps,edx
  1886.     };
  1887.         Pps--;
  1888. /*this is a place for new code*/
  1889.     //╬ß⌡εΣΦ∞ ±∩≡αΓα
  1890.     bool RightPrefer=true;
  1891.     int Rtx;//current point 
  1892.     int Rty;
  1893.     int Ltx;
  1894.     int Lty;
  1895.     byte Rpx[MaxP];//right path
  1896.     byte Rpy[MaxP];
  1897.     byte Lpx[MaxP];//left path
  1898.     byte Lpy[MaxP];
  1899.     int Rpp=1;//index of current point
  1900.     bool LDoing,RDoing;//=true if last point reached
  1901.     byte Rdirc;//currend direction
  1902.     byte Ldirc;
  1903.     int Rmaxalt;//maximum alteration,right path
  1904.     int Lmaxalt;//maximum alteration,left path
  1905.     int Rppm=0;
  1906.     int Lppm=0;
  1907.     int Rcum=0;
  1908.     int Rcum1=0;
  1909.     int Lcum=0;
  1910.     int Lcum1=0;
  1911.     byte Trr=TrMap[y][x];
  1912.     TrMap[y][x]=0;
  1913.     //╚Σσ∞, ∩εΩα φσ ≤∩≡σ∞±  Γ ±≥σφΩ≤
  1914.     __asm{
  1915.         xor        ebx,ebx
  1916.         mov        ecx,Pps
  1917.         xor        edx,edx //Rpp
  1918.         mov        al,[xx+edx]
  1919.         mov        [Rpx+edx],al
  1920.         mov        [Lpx+edx],al
  1921.         mov        al,[yy+edx]
  1922.         mov        [Rpy+edx],al
  1923.         mov        [Lpy+edx],al
  1924.         inc        edx
  1925. uuu_Loop:
  1926.         mov        al,[xx+edx]
  1927.         mov        [Rpx+edx],al
  1928.         mov        [Lpx+edx],al
  1929.         mov        bl,al
  1930.         mov        al,[yy+edx]
  1931.         mov        [Rpy+edx],al
  1932.         mov        [Lpy+edx],al
  1933.         mov        bh,al
  1934. //        add        bx,0101h
  1935.         cmp        byte ptr[TrMap+ebx],0
  1936.         jnz        uuu_end
  1937.         inc        edx
  1938.         loop    uuu_Loop        
  1939. uuu_end:
  1940.         //shr        edx,1
  1941.         mov        Rpp,edx
  1942.     };
  1943.     Rtx=xx[Rpp-1];
  1944.     Rty=yy[Rpp-1];
  1945.     /*Rpx[0]=Rtx;
  1946.     Rpy[0]=Rty;
  1947.     Lpx[0]=Rtx;
  1948.     Lpy[0]=Rty;
  1949.     do{ 
  1950.         Rtx=xx[Rpp];
  1951.         Rty=yy[Rpp];
  1952.         Rpx[Rpp]=Rtx;
  1953.         Rpy[Rpp]=Rty;
  1954.         Lpx[Rpp]=Rtx;
  1955.         Lpy[Rpp]=Rty;
  1956.         Rpp++;
  1957.     }while(!TrMap[Rty][Rtx]&&(Rtx!=x1||Rty!=y1));*/
  1958.     // ┼±δΦ dx>dy,≥ε φα ΩαµΣε∞ °απ≤ dx Φτ∞σφ σ≥  ±≥≡επε φα 1
  1959.     if(Rtx!=x1||Rty!=y1){
  1960.         //LLock[y][x]=false;
  1961.         Rpp-=1;
  1962.         Rtx=xx[Rpp];
  1963.         Rty=yy[Rpp];
  1964.         Ltx=xx[Rpp];
  1965.         Lty=yy[Rpp];
  1966.         int Ppi=Rpp+1;
  1967.         LDoing=true;
  1968.         RDoing=true;
  1969.         //╚∙σ∞, ∩εΩα φα⌡εΣΦ∞±  Γ ταφ ≥εΘ τεφσ
  1970.         while(TrMap[yy[Ppi]][xx[Ppi]]&&Ppi<Pps)Ppi++;
  1971.         if(Ppi>Pps)RDoing=false;//╩εφ.≥ε≈Ωα φσΣε±≥ΦµΦ∞α
  1972.         int Xls=xx[Ppi-1];
  1973.         int Yls=yy[Ppi-1];
  1974.         //╙∩σ≡δΦ±ⁿ...┬√≈Φ±δ σ∞ φα∩≡αΓδσφΦσ ΣΓΦµσφΦ 
  1975.         Rdirc=drr[(xx[Rpp+1]-xx[Rpp]+1)*3+yy[Rpp+1]-yy[Rpp]+1];
  1976.         Ldirc=Rdirc;
  1977.         //┬√ßΦ≡ασ∞ φα≈αδⁿφεσ φα∩≡αΓδσφΦσ-right
  1978.         FillCirc(Rtx,Rty);
  1979.         int dirc1=(Rdirc+1)&7;
  1980.         for(int z=0;circ[dirc1]&&z<7;dirc1++,z++);
  1981.         Rdirc=dirc1&7;
  1982.         //-left
  1983.         dirc1=8+((Ldirc+7)&7);
  1984.         for(z=0;circ[dirc1]&&z<7;dirc1--,z++);
  1985.         Ldirc=dirc1&7;
  1986.         //╚Σσ∞ ∩ε ∩≡αΓε∞≤ Ω≡α■ Σε ≥σ⌡ ∩ε≡ ∩εΩα ΓφεΓⁿ φσ ∩σ≡σ±σ-
  1987.         //≈σ∞±  ± ∩≡ ∞εΘ δΦφΦσΘ, ±εσΣΦφ ■∙σΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■
  1988.         //≥ε≈ΩΦ
  1989.         Rmaxalt=0;
  1990.         Lmaxalt=0;
  1991.         while(Rpp<MaxP-8&&LDoing&&RDoing){
  1992.             //∩√≥ασ∞±  ∩εΓσ≡φ≤≥ⁿ φα∩≡αΓε
  1993.             FillCirc(Rtx,Rty);
  1994.             int dirc1=(Rdirc+7)&7;
  1995.             for(int z=0;z<6&&circ[dirc1];dirc1++,z++);
  1996.             Rdirc=dirc1&7;
  1997.             Rpp++;
  1998.             int Tdx=idrx[Rdirc];
  1999.             int Tdy=idry[Rdirc];
  2000.             Rcum-=sdy*Tdx;
  2001.             Rcum+=sdx*Tdy;
  2002.             Rtx+=Tdx;
  2003.             Rty+=Tdy;
  2004.             Rpx[Rpp]=Rtx;Rpy[Rpp]=Rty;
  2005.             //the same, but left
  2006.             FillCirc(Ltx,Lty);
  2007.             dirc1=8+((Ldirc+1)&7);
  2008.             for(z=0;z<6&&circ[dirc1];dirc1--,z++);
  2009.             Ldirc=dirc1&7;
  2010.             Tdx=idrx[Ldirc];
  2011.             Tdy=idry[Ldirc];
  2012.             Lcum+=sdy*Tdx;
  2013.             Lcum-=sdx*Tdy;
  2014.             Ltx+=Tdx;
  2015.             Lty+=Tdy;
  2016.             Lpx[Rpp]=Ltx;Lpy[Rpp]=Lty;
  2017.             //┬√≈Φ±δ σ∞ τφα≈σφΦσ y φα ∩≡ ∞εΘ δΦφΦΦ, ±εε≥Γ. 
  2018.             //Σαφφε∞≤ x
  2019.             if(Rcum<=0&&Rcum1>=0){
  2020.                 if(dx>dy){
  2021.                     if(sx>0){
  2022.                         if(Rtx>=Xls)RDoing=false;
  2023.                     }else if(Rtx<=Xls)RDoing=false;
  2024.                 }else{
  2025.                     if(sy>0){
  2026.                         if(Rty>=Yls)RDoing=false;
  2027.                     }else if(Rty<=Yls)RDoing=false;
  2028.                 };
  2029.                 if(!RDoing)RightPrefer=true;
  2030.             };
  2031.             //┬√≈Φ±δ σ∞ ∞αΩ±Φ∞αδⁿφεσ ε≥ΩδεφσφΦσ ε≥ ∩≡ ∞εΘ δΦφΦΦ
  2032.             if(Rcum>=Rmaxalt){
  2033.                 Rmaxalt=Rcum;
  2034.                 Rppm=Rpp;
  2035.             };
  2036.             Rcum1=Rcum;
  2037.             //the same for left
  2038.             if(Lcum<=0&&Lcum1>=0){
  2039.                 if(dx>dy){
  2040.                     if(sx>0){
  2041.                         if(Ltx>=Xls)LDoing=false;
  2042.                     }else if(Ltx<=Xls)LDoing=false;
  2043.                 }else{
  2044.                     if(sy>0){
  2045.                         if(Lty>=Yls)LDoing=false;
  2046.                     }else if(Lty<=Yls)LDoing=false;
  2047.                 };
  2048.                 if(!LDoing)RightPrefer=false;
  2049.             };
  2050.             //┬√≈Φ±δ σ∞ ∞αΩ±Φ∞αδⁿφεσ ε≥ΩδεφσφΦσ ε≥ ∩≡ ∞εΘ δΦφΦΦ
  2051.             if(Lcum>=Lmaxalt){
  2052.                 Lmaxalt=Lcum;
  2053.                 Lppm=Rpp;
  2054.             };
  2055.             Lcum1=Lcum;
  2056.         };
  2057.         //LLock[y][x]=true;
  2058.         if(Rpp<MaxP-9){
  2059.             if(RightPrefer){
  2060.                 if(Rppm+1<Rpp)Rppm+=1;else Rppm=Rpp;
  2061.                 memcpy(xx,Rpx,(Rppm+1));
  2062.                 memcpy(yy,Rpy,(Rppm+1));
  2063.                 Pps=Rppm;
  2064.             }else{
  2065.                 if(Lppm+1<Rpp)Lppm+=1;else Lppm=Rpp;
  2066.                 memcpy(xx,Lpx,(Lppm+1));
  2067.                 memcpy(yy,Lpy,(Lppm+1));
  2068.                 Pps=Lppm;
  2069.             };
  2070.         }else return;
  2071.         //╬∩≥Φ∞Φτα÷Φ  ∩≤≥Φ
  2072.         //Pps=Optima1(Pps);
  2073.     };
  2074.     TrMap[y][x]=Trr;
  2075.     NowBuf=GetAsmBlock();
  2076.     if(!int(NowBuf))return;
  2077.     Ofst=0;
  2078.     memcpy(&NowBuf[OneAsmSize-4],&Ofst,4);
  2079.     InLineCom=NowBuf;
  2080.     LineOffset=0;
  2081.     cmLoadAnm(AnmGoKind,1,0);
  2082.     //cmLoadAnm(1,1,0);
  2083.     cmLoadAnm(AnmStandKind,0,0);
  2084.     for(int i=1;i<=Pps;i++){
  2085.         //byte (*XXX)[64];
  2086.         //memcpy(&XXX,&NowBuf,4);
  2087.         //cmSetDir(xx[i]-xx[i-1],yy[i]-yy[i-1]);
  2088.         if(i==1)cmPerfAnm(0);//-------??????????????????????
  2089.         cmSetXY(xx[i]-xx[i-1],yy[i]-yy[i-1]);
  2090.         //cmPerfAnm(1);
  2091.         //cmSetXYDirX(xx[i],yy[i],xx[i]-xx[i-1],yy[i]-yy[i-1],1);
  2092.         //cmPerfAnm(1);
  2093.     };
  2094.     cmLoadAnm(AnmStandKind,0,0);
  2095.     cmPerfAnm(0);
  2096.     //cmDone();
  2097.     cmRet();
  2098. };
  2099. int GetRAngle(int dx,int dy,int Angle){
  2100.     int ang;
  2101.     int sx=abs(dx);
  2102.     int sy=abs(dy);
  2103.     if(!(dx||dy))return 0;
  2104.     if(sx>sy){
  2105.         ang=div(dy<<8,sx).quot;
  2106.         if(dx<0)ang=1024-ang;
  2107.     }else{
  2108.         ang=512-div(dx<<8,sy).quot;
  2109.         if(dy<0)ang=2048-ang;
  2110.     };
  2111.     ang=Angle-ang;
  2112.     while(ang<0)ang+=2048;
  2113.     if(ang>1792)ang-=2048;
  2114.     return ang;
  2115. };
  2116. int GetLAngle(int dx,int dy,int Angle){
  2117.     int ang;
  2118.     int sx=abs(dx);
  2119.     int sy=abs(dy);
  2120.     if(!(dx||dy))return 0;
  2121.     if(sx>sy){
  2122.         ang=div(dy<<8,sx).quot;
  2123.         if(dx<0)ang=1024-ang;
  2124.     }else{
  2125.         ang=512-div(dx<<8,sy).quot;
  2126.         if(dy<0)ang=2048-ang;
  2127.     };
  2128.     ang-=Angle;
  2129.     while(ang<0)ang+=2048;
  2130.     if(ang>1792)ang-=2048;
  2131.     return ang;
  2132. };
  2133. void OneObject::CreatePrePath(int x1,int y1){
  2134.     PathAsks++;
  2135.     TrMap[y][x]=0;
  2136.     int sdx=x1-x;
  2137.     int    sdy=y1-y;
  2138.     int    Cum=0;
  2139.     int Pps=0;
  2140.     int sx=(sdx>0)?1:-1;
  2141.     int sy=(sdy>0)?1:-1;
  2142.     int dx=abs(sdx);
  2143.     int dy=abs(sdy);
  2144.     int    Mdx=dx;
  2145.     int    Mdy=dy;
  2146.     int    Mx=x;
  2147.     int    My=y;
  2148.     int    xx1=x;
  2149.     int yy1=y;
  2150.     int rx=sx;
  2151.     int ry=sy;
  2152.     if(dx>dy)ry=0;
  2153.     if(dy>dx)rx=0;
  2154.     int Angle0=GetLAngle(x1-x,y1-y,0);
  2155.     int Angle;
  2156.     int ddx,ddy;
  2157.     int Lvp=0;
  2158.     int Rvp=0;
  2159.     bool LvpLast=false;
  2160.     bool RvpLast=false;
  2161.     if(PathX)free(PathX);
  2162.     if(PathY)free(PathY);
  2163.     PathX=NULL;
  2164.     PathY=NULL;
  2165.     NIPoints=0;
  2166.     CurIPoint=0;
  2167.     NeedPath=false;
  2168.     //±εσΣΦφ σ∞ δΦφΦσΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■ ≥ε≈ΩΦ. 
  2169.     //╬∩≥Φ∞Φτα÷Φ  ≥εδⁿΩε ∩ε ±Ωε≡ε±≥Φ
  2170.     __asm{
  2171.         mov        ax,word ptr Mdx
  2172.         mov        bx,word ptr Mdy
  2173.         xor        edx,edx  //Pps
  2174.         xor        ecx,ecx  //Cum
  2175.         mov        si,word ptr Mx
  2176.         mov        di,word ptr My
  2177.         cmp        bx,ax
  2178.         jae        Lp5xx
  2179.         //dx>dy
  2180.         mov        word ptr[xx+edx],si
  2181.         mov        word ptr[yy+edx],di
  2182.         inc        edx
  2183.         or        ax,ax
  2184.         jz        LoopsEnd
  2185.         cmp        sy,0
  2186.         jl        Lp3xx
  2187.         cmp        sx,0
  2188.         jl        Lp2begin
  2189.         //dx>dy,sx>0,sy>0
  2190. Lp1begin:
  2191.         inc        si    //x++
  2192.         add        cx,bx
  2193.         cmp        cx,word ptr Mdx
  2194.         jb        Lp1_1
  2195.         sub        cx,word ptr Mdx
  2196.         inc        di  //y++
  2197. Lp1_1:
  2198.         mov        word ptr[xx+edx],si
  2199.         mov        word ptr[yy+edx],di
  2200.         inc        edx
  2201.         dec        ax
  2202.         jnz        Lp1begin
  2203.         jmp        LoopsEnd
  2204. Lp2begin: //dx>dy,sx<0,sy>0
  2205.         dec        si    //x--
  2206.         add        cx,bx
  2207.         cmp        cx,word ptr Mdx
  2208.         jb        Lp2_1
  2209.         sub        cx,word ptr Mdx
  2210.         inc        di //y++
  2211. Lp2_1:
  2212.         mov        word ptr[xx+edx],si
  2213.         mov        word ptr[yy+edx],di
  2214.         inc        edx
  2215.         dec        ax
  2216.         jnz        Lp2begin
  2217.         jmp        LoopsEnd
  2218. Lp3xx:    //dy<0
  2219.         cmp        sx,0
  2220.         jl        Lp4begin
  2221. Lp3begin: //dx>dy,sx>0,sy<0
  2222.         inc        si    //x++
  2223.         add        cx,bx
  2224.         cmp        cx,word ptr Mdx
  2225.         jb        Lp3_1
  2226.         sub        cx,word ptr Mdx
  2227.         dec        di //y--
  2228. Lp3_1:
  2229.         mov        word ptr[xx+edx],si
  2230.         mov        word ptr[yy+edx],di
  2231.         inc        edx
  2232.         dec        ax
  2233.         jnz        Lp3begin
  2234.         jmp        LoopsEnd
  2235. Lp4begin: //dx>dy,sx<0,sy<0
  2236.         dec        si    //x--
  2237.         add        cx,bx
  2238.         cmp        cx,word ptr Mdx
  2239.         jb        Lp4_1
  2240.         sub        cx,word ptr Mdx
  2241.         dec        di //y--
  2242. Lp4_1:
  2243.         mov        word ptr[xx+edx],si
  2244.         mov        word ptr[yy+edx],di
  2245.         inc        edx
  2246.         dec        ax
  2247.         jnz        Lp4begin
  2248.         jmp        LoopsEnd
  2249. Lp5xx:    //dx<dy
  2250.         mov        word ptr[xx+edx],si
  2251.         mov        word ptr[yy+edx],di
  2252.         inc        edx
  2253.         or        bx,bx
  2254.         jz        LoopsEnd
  2255.         cmp        sx,0
  2256.         jl        Lp7xx
  2257.         cmp        sy,0
  2258.         jl        Lp6begin
  2259. Lp5Begin:
  2260.         inc        di    //y++
  2261.         add        cx,ax
  2262.         cmp        cx,word ptr dy
  2263.         jb        Lp5_1
  2264.         sub        cx,word ptr dy
  2265.         inc        si    //x++
  2266. Lp5_1:
  2267.         mov        word ptr[xx+edx],si
  2268.         mov        word ptr[yy+edx],di
  2269.         inc        edx
  2270.         dec        bx
  2271.         jnz        Lp5begin
  2272.         jmp        LoopsEnd
  2273. Lp6Begin://sx>0,sy<0
  2274.         dec        di    //y++
  2275.         add        cx,ax
  2276.         cmp        cx,word ptr dy
  2277.         jb        Lp6_1
  2278.         sub        cx,word ptr dy
  2279.         inc        si    //x++
  2280. Lp6_1:
  2281.         mov        word ptr[xx+edx],si
  2282.         mov        word ptr[yy+edx],di
  2283.         inc        edx
  2284.         dec        bx
  2285.         jnz        Lp6begin
  2286.         jmp        LoopsEnd
  2287. Lp7xx:    //dx<0
  2288.         cmp        sy,0
  2289.         jl        Lp8begin
  2290. Lp7Begin://dx<0,dy>0
  2291.         inc        di    //y++
  2292.         add        cx,ax
  2293.         cmp        cx,word ptr dy
  2294.         jb        Lp7_1
  2295.         sub        cx,word ptr dy
  2296.         dec        si    //x--
  2297. Lp7_1:
  2298.         mov        word ptr[xx+edx],si
  2299.         mov        word ptr[yy+edx],di
  2300.         inc        edx
  2301.         dec        bx
  2302.         jnz        Lp7begin
  2303.         jmp        LoopsEnd
  2304. Lp8Begin://dx<0,dy<0
  2305.         dec        di    //y--
  2306.         add        cx,ax
  2307.         cmp        cx,word ptr dy
  2308.         jb        Lp8_1
  2309.         sub        cx,word ptr dy
  2310.         dec        si    //x--
  2311. Lp8_1:
  2312.         mov        word ptr[xx+edx],si
  2313.         mov        word ptr[yy+edx],di
  2314.         inc        edx
  2315.         dec        bx
  2316.         jnz        Lp8begin
  2317. loopsEnd:
  2318.         //shr        edx,1
  2319.         mov        Pps,edx
  2320.     };
  2321.         Pps--;
  2322. /*this is a place for new code*/
  2323.     //╬ß⌡εΣΦ∞ ±∩≡αΓα
  2324.     bool RightPrefer=true;
  2325.     int Rtx;//current point 
  2326.     int Rty;
  2327.     int Ltx;
  2328.     int Lty;
  2329.     byte Rpx[MaxP];//right path
  2330.     byte Rpy[MaxP];
  2331.     byte Lpx[MaxP];//left path
  2332.     byte Lpy[MaxP];
  2333.     int Rpp=1;//index of current point
  2334.     bool LDoing;//=true if last point reached
  2335.     bool RDoing;
  2336.     byte Rdirc;//currend direction
  2337.     byte Ldirc;
  2338.     int Rmaxalt;//maximum alteration,right path
  2339.     int Lmaxalt;//maximum alteration,left path
  2340.     int Rppm=0;
  2341.     int Lppm=0;
  2342.     int Rcum=0;
  2343.     int Rcum1=0;
  2344.     int Lcum=0;
  2345.     int Lcum1=0;
  2346.     byte Trr=TrMap[y][x];
  2347.     TrMap[y][x]=0;
  2348.     //╚Σσ∞, ∩εΩα φσ ≤∩≡σ∞±  Γ ±≥σφΩ≤
  2349.     __asm{
  2350.         xor        ebx,ebx
  2351.         mov        ecx,Pps
  2352.         xor        edx,edx //Rpp
  2353.         mov        al,[xx+edx]
  2354.         mov        [Rpx+edx],al
  2355.         mov        [Lpx+edx],al
  2356.         mov        al,[yy+edx]
  2357.         mov        [Rpy+edx],al
  2358.         mov        [Lpy+edx],al
  2359.         inc        edx
  2360. uuu_Loop:
  2361.         mov        al,[xx+edx]
  2362.         mov        [Rpx+edx],al
  2363.         mov        [Lpx+edx],al
  2364.         mov        bl,al
  2365.         mov        al,[yy+edx]
  2366.         mov        [Rpy+edx],al
  2367.         mov        [Lpy+edx],al
  2368.         mov        bh,al
  2369. //        add        bx,0101h
  2370.         cmp        byte ptr[TrMap+ebx],0
  2371.         jnz        uuu_end
  2372.         inc        edx
  2373.         loop    uuu_Loop        
  2374. uuu_end:
  2375.         //shr        edx,1
  2376.         mov        Rpp,edx
  2377.     };
  2378.     Rtx=xx[Rpp-1];
  2379.     Rty=yy[Rpp-1];
  2380.     
  2381.     // ┼±δΦ dx>dy,≥ε φα ΩαµΣε∞ °απ≤ dx Φτ∞σφ σ≥  ±≥≡επε φα 1
  2382.     if(Rtx!=x1||Rty!=y1){
  2383.         //LLock[y][x]=false;
  2384.         Rpp-=1;
  2385.         Rtx=xx[Rpp];
  2386.         Rty=yy[Rpp];
  2387.         Ltx=xx[Rpp];
  2388.         Lty=yy[Rpp];
  2389.         int Ppi=Rpp+1;
  2390.         LDoing=true;
  2391.         RDoing=true;
  2392.         //╚∙σ∞, ∩εΩα φα⌡εΣΦ∞±  Γ ταφ ≥εΘ τεφσ
  2393.         while(TrMap[yy[Ppi]][xx[Ppi]]&&Ppi<Pps)Ppi++;
  2394.         if(Ppi>Pps)LDoing=false;//╩εφ.≥ε≈Ωα φσΣε±≥ΦµΦ∞α
  2395.         int Xls=xx[Ppi-1];
  2396.         int Yls=yy[Ppi-1];
  2397.         //╙∩σ≡δΦ±ⁿ...┬√≈Φ±δ σ∞ φα∩≡αΓδσφΦσ ΣΓΦµσφΦ 
  2398.         Rdirc=drr[(xx[Rpp+1]-xx[Rpp]+1)*3+yy[Rpp+1]-yy[Rpp]+1];
  2399.         Ldirc=Rdirc;
  2400.         //┬√ßΦ≡ασ∞ φα≈αδⁿφεσ φα∩≡αΓδσφΦσ-right
  2401.         FillCirc(Rtx,Rty);
  2402.         int dirc1=(Rdirc+1)&7;
  2403.         for(int z=0;circ[dirc1]&&z<7;dirc1++,z++);
  2404.         Rdirc=dirc1&7;
  2405.         //-left
  2406.         dirc1=8+((Ldirc+7)&7);
  2407.         for(z=0;circ[dirc1]&&z<7;dirc1--,z++);
  2408.         Ldirc=dirc1&7;
  2409.         //╚Σσ∞ ∩ε ∩≡αΓε∞≤ Ω≡α■ Σε ≥σ⌡ ∩ε≡ ∩εΩα ΓφεΓⁿ φσ ∩σ≡σ±σ-
  2410.         //≈σ∞±  ± ∩≡ ∞εΘ δΦφΦσΘ, ±εσΣΦφ ■∙σΘ φα≈αδⁿφ≤■ Φ Ωεφσ≈φ≤■
  2411.         //≥ε≈ΩΦ
  2412.         Rmaxalt=0;
  2413.         Lmaxalt=0;
  2414.         while(Rpp<MaxP-8&&LDoing&&RDoing){
  2415.             //∩√≥ασ∞±  ∩εΓσ≡φ≤≥ⁿ φα∩≡αΓε
  2416.             FillCirc(Rtx,Rty);
  2417.             int dirc1=(Rdirc+7)&7;
  2418.             for(int z=0;z<6&&circ[dirc1];dirc1++,z++);
  2419.             Rdirc=dirc1&7;
  2420.             Rpp++;
  2421.             int Tdx=idrx[Rdirc];
  2422.             int Tdy=idry[Rdirc];
  2423.             Rcum-=sdy*Tdx;
  2424.             Rcum+=sdx*Tdy;
  2425.             Rtx+=Tdx;
  2426.             Rty+=Tdy;
  2427.             Rpx[Rpp]=Rtx;Rpy[Rpp]=Rty;
  2428.             Angle=GetLAngle(Rtx-x,Rty-y,Angle0);
  2429.             if(Angle>Rmaxalt){
  2430.                 Rmaxalt=Angle;
  2431.                 Rppm=Rpp;
  2432.             };
  2433.             //∩≡εΓσ≡ σ∞ ≤±δεΓΦσ ∩≡ ∞εΘ ΓΦΣΦ∞ε±≥Φ
  2434.             ddx=x1-Rtx;
  2435.             ddy=y1-Rty;
  2436.             if(ddx>1)ddx=1;
  2437.             if(ddx<-1)ddx=-1;
  2438.             if(ddy>1)ddy=1;
  2439.             if(ddy<-1)ddy=-1;
  2440.             if(!TrMap[Rty+ddy][Rtx+ddx]){
  2441.                 if(!RvpLast){
  2442.                     Rvp=Rpp;
  2443.                     RvpLast=true;
  2444.                 };
  2445.             }else RvpLast=false;
  2446.             //the same, but left
  2447.             FillCirc(Ltx,Lty);
  2448.             dirc1=8+((Ldirc+1)&7);
  2449.             for(z=0;z<6&&circ[dirc1];dirc1--,z++);
  2450.             Ldirc=dirc1&7;
  2451.             Tdx=idrx[Ldirc];
  2452.             Tdy=idry[Ldirc];
  2453.             Lcum+=sdy*Tdx;
  2454.             Lcum-=sdx*Tdy;
  2455.             Ltx+=Tdx;
  2456.             Lty+=Tdy;
  2457.             Lpx[Rpp]=Ltx;Lpy[Rpp]=Lty;
  2458.             Angle=GetRAngle(Ltx-x,Lty-y,Angle0);
  2459.             if(Angle>Lmaxalt){
  2460.                 Lmaxalt=Angle;
  2461.                 Lppm=Rpp;
  2462.             };
  2463.             //∩≡εΓσ≡ σ∞ ≤±δεΓΦσ ∩≡ ∞εΘ ΓΦΣΦ∞ε±≥Φ
  2464.             ddx=x1-Ltx;
  2465.             ddy=y1-Lty;
  2466.             if(ddx>1)ddx=1;
  2467.             if(ddx<-1)ddx=-1;
  2468.             if(ddy>1)ddy=1;
  2469.             if(ddy<-1)ddy=-1;
  2470.             if(!TrMap[Lty+ddy][Ltx+ddx]){
  2471.                 if(!LvpLast){
  2472.                     Lvp=Rpp;
  2473.                     LvpLast=true;
  2474.                 };
  2475.             }else LvpLast=false;
  2476.             //┬√≈Φ±δ σ∞ τφα≈σφΦσ y φα ∩≡ ∞εΘ δΦφΦΦ, ±εε≥Γ. 
  2477.             //Σαφφε∞≤ x
  2478.             if(Rcum<=0&&Rcum1>=0){
  2479.                 if(dx>dy){
  2480.                     if(sx>0){
  2481.                         if(Rtx>=Xls)RDoing=false;
  2482.                     }else if(Rtx<=Xls)RDoing=false;
  2483.                 }else{
  2484.                     if(sy>0){
  2485.                         if(Rty>=Yls)RDoing=false;
  2486.                     }else if(Rty<=Yls)RDoing=false;
  2487.                 };
  2488.                 if(!RDoing)RightPrefer=true;
  2489.             };
  2490.             Rcum1=Rcum;
  2491.             //the same for left
  2492.             if(Lcum<=0&&Lcum1>=0){
  2493.                 if(dx>dy){
  2494.                     if(sx>0){
  2495.                         if(Ltx>=Xls)LDoing=false;
  2496.                     }else if(Ltx<=Xls)LDoing=false;
  2497.                 }else{
  2498.                     if(sy>0){
  2499.                         if(Lty>=Yls)LDoing=false;
  2500.                     }else if(Lty<=Yls)LDoing=false;
  2501.                 };
  2502.                 if(!LDoing)RightPrefer=false;
  2503.             };
  2504.             Lcum1=Lcum;
  2505.         };
  2506.         //LLock[y][x]=true;
  2507.         if(Rpp<MaxP-9){
  2508.             if(RightPrefer){
  2509.                 //if(Rppm+1<Rpp)Rppm+=1;else Rppm=Rpp;
  2510.                 //memcpy(xx,Rpx,(Rppm+1));
  2511.                 //memcpy(yy,Rpy,(Rppm+1));
  2512.                 Pps=Rppm;
  2513.             }else{
  2514.                 //if(Lppm+1<Rpp)Lppm+=1;else Lppm=Rpp;
  2515.                 //memcpy(xx,Lpx,(Lppm+1));
  2516.                 //memcpy(yy,Lpy,(Lppm+1));
  2517.                 Pps=Lppm;
  2518.                 Rvp=Lvp;
  2519.                 
  2520.             };
  2521.             if(Rvp<Pps)Rvp=Pps;
  2522.             NIPoints=Rvp-Pps+1;
  2523.             int maxp=NIPoints;
  2524.             CurIPoint=0;
  2525.             if(NIPoints>2){
  2526.                 NIPoints=2+((NIPoints-2)>>2);
  2527.             };
  2528.             PathX=new byte [NIPoints];
  2529.             PathY=new byte [NIPoints];
  2530.             if(RightPrefer){
  2531.                 if(maxp<=2){
  2532.                     memcpy(PathX,&Rpx[Pps],NIPoints);
  2533.                     memcpy(PathY,&Rpy[Pps],NIPoints);
  2534.                 }else{
  2535.                     int np=((maxp-2)>>2)+1;
  2536.                     for(int nn=0;nn<np;nn++){
  2537.                         PathX[nn]=Rpx[Pps+(nn<<2)];
  2538.                         PathY[nn]=Rpy[Pps+(nn<<2)];
  2539.                     };
  2540.                     PathX[nn]=Rpx[Pps+maxp-1];
  2541.                     PathY[nn]=Rpy[Pps+maxp-1];
  2542.                 };
  2543.             }else{
  2544.                 if(maxp<=2){
  2545.                     memcpy(PathX,&Lpx[Pps],NIPoints);
  2546.                     memcpy(PathY,&Lpy[Pps],NIPoints);
  2547.                 }else{
  2548.                     int np=((maxp-2)>>2)+1;
  2549.                     for(int nn=0;nn<np;nn++){
  2550.                         PathX[nn]=Lpx[Pps+(nn<<2)];
  2551.                         PathY[nn]=Lpy[Pps+(nn<<2)];
  2552.                     };
  2553.                     PathX[nn]=Lpx[Pps+maxp-1];
  2554.                     PathY[nn]=Lpy[Pps+maxp-1];
  2555.                 };
  2556.             };
  2557.             /*if(rando()<10000){
  2558.                 bool ttt=rando()<13000;
  2559.                 int vx,vy;
  2560.                 for(int i=0;i<NIPoints;i++){
  2561.                     vx=0;
  2562.                     vy=0;
  2563.                     int xxx=PathX[i];
  2564.                     int yyy=PathY[i];
  2565.                     for(int dd=0;dd<8;dd++){
  2566.                         int dx=idrx[dd];
  2567.                         int dy=idry[dd];
  2568.                         if(TrMap[yyy+dy][xxx+dx]){
  2569.                             vx-=dx;
  2570.                             vy-=dy;
  2571.                         };
  2572.                     };
  2573.                     if(vx>1)vx=-1;
  2574.                     if(vx<-1)vx=-1;
  2575.                     if(vy>1)vy=1;
  2576.                     if(vy<-1)vy=-1;
  2577.                     if(!TrMap[xxx+vx][yyy+vy]){
  2578.                         if(ttt&&!TrMap[xxx+vx+vx][yyy+vy+vy]){
  2579.                             PathX[i]=xxx+vx+vx;
  2580.                             PathY[i]=yyy+vy+vy;
  2581.                         }else{
  2582.                             PathX[i]=xxx+vx;
  2583.                             PathY[i]=yyy+vy;
  2584.                         };
  2585.                     };
  2586.                 };
  2587.             };*/
  2588.             NeedPath=true;
  2589.         }else return;
  2590.     };
  2591. };
  2592. inline void ReMemCirc(byte x,byte y){
  2593.     __asm{
  2594.         xor        ebx,ebx
  2595.         mov        bh,byte ptr y
  2596.         mov        bl,byte ptr x
  2597.         add        ebx,offset TrMap
  2598.         mov        al,circ[0]
  2599.         mov        [ebx-256],al
  2600.         mov        al,circ[1]
  2601.         mov        [ebx-255],al
  2602.         mov        al,circ[2]
  2603.         mov        [ebx+1],al
  2604.         mov        al,circ[3]
  2605.         mov        [ebx+257],al
  2606.         mov        al,circ[4]
  2607.         mov        [ebx+256],al
  2608.         mov        al,circ[5]
  2609.         mov        [ebx+255],al
  2610.         mov        al,circ[6]
  2611.         mov        [ebx-1],al
  2612.         mov        al,circ[7]
  2613.         mov        [ebx-257],al
  2614.         xor        ebx,ebx
  2615.         mov        bh,byte ptr y
  2616.         mov        bl,byte ptr x
  2617.         add        ebx,offset LLock
  2618.         mov        al,circ[8]
  2619.         mov        [ebx-256],al
  2620.         mov        al,circ[9]
  2621.         mov        [ebx-255],al
  2622.         mov        al,circ[10]
  2623.         mov        [ebx+1],al
  2624.         mov        al,circ[11]
  2625.         mov        [ebx+257],al
  2626.         mov        al,circ[12]
  2627.         mov        [ebx+256],al
  2628.         mov        al,circ[13]
  2629.         mov        [ebx+255],al
  2630.         mov        al,circ[14]
  2631.         mov        [ebx-1],al
  2632.         mov        al,circ[15]
  2633.         mov        [ebx-257],al
  2634.     }
  2635. };
  2636. inline void MemCirc(byte x,byte y){
  2637.     __asm{
  2638.         xor        ebx,ebx
  2639.         mov        bh,byte ptr y
  2640.         mov        bl,byte ptr x
  2641.         add        ebx,offset TrMap
  2642.         mov        al,[ebx-256]
  2643.         mov        circ[0],al
  2644.         mov        al,[ebx-255]
  2645.         mov        circ[1],al
  2646.         mov        al,[ebx+1]
  2647.         mov        circ[2],al
  2648.         mov        al,[ebx+257]
  2649.         mov        circ[3],al
  2650.         mov        al,[ebx+256]
  2651.         mov        circ[4],al
  2652.         mov        al,[ebx+255]
  2653.         mov        circ[5],al
  2654.         mov        al,[ebx-1]
  2655.         mov        circ[6],al
  2656.         mov        al,[ebx-257]
  2657.         mov        circ[7],al
  2658.         xor        ebx,ebx
  2659.         mov        bh,byte ptr y
  2660.         mov        bl,byte ptr x
  2661.         add        ebx,offset LLock
  2662.         mov        al,[ebx-256]
  2663.         mov        circ[8],al
  2664.         mov        al,[ebx-255]
  2665.         mov        circ[9],al
  2666.         mov        al,[ebx+1]
  2667.         mov        circ[10],al
  2668.         mov        al,[ebx+257]
  2669.         mov        circ[11],al
  2670.         mov        al,[ebx+256]
  2671.         mov        circ[12],al
  2672.         mov        al,[ebx+255]
  2673.         mov        circ[13],al
  2674.         mov        al,[ebx-1]
  2675.         mov        circ[14],al
  2676.         mov        al,[ebx-257]
  2677.         mov        circ[15],al
  2678.     }
  2679. };
  2680. inline void FCirc(byte x,byte y,byte x0,byte y0,byte x1,byte y1){
  2681.     __asm{
  2682.         xor        ebx,ebx
  2683.         mov        bl,x
  2684.         mov        bh,y
  2685.         cmp        bl,x0
  2686.         jne        lb1
  2687.         mov        TrMap[ebx-257],1
  2688.         mov        TrMap[ebx-1],1
  2689.         mov        TrMap[ebx+255],1
  2690.         mov        LLock[ebx-257],1
  2691.         mov        LLock[ebx-1],1
  2692.         mov        LLock[ebx+255],1
  2693. lb1:    cmp        bl,x1
  2694.         jne        lb2
  2695.         mov        TrMap[ebx-255],1
  2696.         mov        TrMap[ebx+1],1
  2697.         mov        TrMap[ebx+257],1
  2698.         mov        LLock[ebx-255],1
  2699.         mov        LLock[ebx+1],1
  2700.         mov        LLock[ebx+257],1
  2701. lb2:    cmp        bh,y0
  2702.         jne        lb3
  2703.         mov        TrMap[ebx-257],1
  2704.         mov        TrMap[ebx-256],1
  2705.         mov        TrMap[ebx-255],1
  2706.         mov        LLock[ebx-257],1
  2707.         mov        LLock[ebx-256],1
  2708.         mov        LLock[ebx-255],1
  2709. lb3:    cmp        bh,y1
  2710.         jne        lb4
  2711.         mov        TrMap[ebx+255],1
  2712.         mov        TrMap[ebx+256],1
  2713.         mov        TrMap[ebx+257],1
  2714.         mov        LLock[ebx+255],1
  2715.         mov        LLock[ebx+256],1
  2716.         mov        LLock[ebx+257],1
  2717. lb4:
  2718.     };
  2719. };
  2720.  
  2721. //Order Type=77
  2722. //╤ΓαδΦ≥ⁿ ± ²≥εΘ ≥ε≈ΩΦ.═σ⌠Φπ τ≡  ±≥ε ≥ⁿ.dir-φα∩≡αΓδσφΦσ,
  2723. //Γ Ωε≥ε≡ε∞ ΣΓΦµσφ≥±  εß┌σΩ≥,Ωε≥ε≡√Θ ∩≡σΣδαπασ≥ Σαφφε∞≤
  2724. //±ΓαδΦ≥ⁿ ± Σε≡επΦ. Γ ²≥ε∞ φα∩≡αΓδσφΦΦ ±ΣΓΦπα≥ⁿ±  δΦ°ⁿ Γ
  2725. //Ω≡αΘφσ∞ ±δ≤≈ασ
  2726. void MFLink(OneObject* OBJ);
  2727. void OneObject::MoveFrom(int dir){
  2728.     //Npush++;
  2729.     if(!cpbMoving)return;
  2730.     if(StandTime<3)return;
  2731.     bool initMXY=true;
  2732.     if(int(LocalOrder))
  2733.         if(LocalOrder->OrderType==77)initMXY=false;
  2734.     if(initMXY){
  2735.         Order1* Or1=GetOrdBlock();
  2736.         if(!int(Or1))return;
  2737.         Or1->PrioryLevel=0;
  2738.         Or1->NextOrder=LocalOrder;
  2739.         Or1->OrderType=77;
  2740.         Or1->OrderTime=0;
  2741.         Or1->info.MoveFrom.dir=dir;
  2742.         //if(int(LocalOrder))FreeOrdBlock(LocalOrder);
  2743.         if(int(InLineCom)){
  2744.             FreeAsmLink();
  2745.             //LoadCurAnm(0);
  2746.         };
  2747.         LocalOrder=Or1;
  2748.         Or1->DoLink=&MFLink;
  2749.         //OrderReport=NULL;
  2750.         //MessageKind=0;
  2751.         //Sender=0xFFFF;
  2752.         //MFLink(this);
  2753.     };
  2754. };
  2755. void MFLink(OneObject* OBJ){
  2756.     byte Direction=OBJ->Direction;
  2757.     byte dir=OBJ->LocalOrder->info.MoveFrom.dir;
  2758.     if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  2759.     OBJ->InLineCom=0;
  2760.     Order1* Loc1=OBJ->LocalOrder->NextOrder;
  2761.     OBJ->FreeOrdBlock(OBJ->LocalOrder);
  2762.     OBJ->LocalOrder=Loc1;
  2763.     int dx0=idrx[Direction];
  2764.     int    dy0=idry[Direction];
  2765.     int x=OBJ->x;
  2766.     int y=OBJ->y;
  2767.     if(OBJ->DrawUp){
  2768.         MemCirc(x,y);
  2769.         FCirc(x,y,OBJ->destX,OBJ->destY,OBJ->destX1,OBJ->destY1);
  2770.     };
  2771.     bool Dfound=false;
  2772.     int ddr;
  2773.     int tx;
  2774.     int ty;
  2775.     if(LLock[y+dy0][x+dx0]/*||dir==Direction*/){
  2776.         if((tmtmt&3)<2){
  2777.             //Turn right
  2778.             ddr=(Direction+1)&7;
  2779.             int z=0;
  2780.             do{
  2781.                 dx0=idrx[ddr];
  2782.                 dy0=idry[ddr];
  2783.                 ddr=(ddr+1)&7;
  2784.                 z++;
  2785.                 tx=x+dx0;
  2786.                 ty=y+dy0;
  2787.                 if(tx>=0&&ty>0&&tx<msx&&ty<msy&&!LLock[ty][tx])break;
  2788.             }while(z<8);
  2789.             ddr=(ddr+7)&7;
  2790.             if(z<8)Dfound=true;
  2791.         } else{
  2792.             //Turn left
  2793.             int ddr=(Direction+7)&7;
  2794.             int z=0;
  2795.             do{
  2796.                 dx0=idrx[ddr];
  2797.                 dy0=idry[ddr];
  2798.                 ddr=(ddr+7)&7;
  2799.                 z++;
  2800.             }while(LLock[y+dy0][x+dx0]&&z<8);
  2801.             ddr=(ddr+1)&7;
  2802.             if(z<8)Dfound=true;
  2803.         };
  2804.     }else{
  2805.         Dfound=true;
  2806.         ddr=Direction;
  2807.     };
  2808.     if(!Dfound&&!LLock[y+dy0][x+dx0]/*&&dir==Direction*/){
  2809.         Dfound=true;
  2810.         ddr=Direction;
  2811.         dx0=idrx[ddr];
  2812.         dy0=idry[ddr];
  2813.     };
  2814.     if(!Dfound){
  2815.         int z=rando();
  2816.         if(z&1){
  2817.             z=z>>1;
  2818.             //Turn right
  2819.             ddr=(Direction+(z&1))&7;
  2820.             int z=0;
  2821.             do{
  2822.                 dx0=idrx[ddr];
  2823.                 dy0=idry[ddr];
  2824.                 ddr=(ddr+1)&7;
  2825.                 z++;
  2826.                 tx=x+dx0;
  2827.                 ty=y+dy0;
  2828.                 if(tx>=0&&ty>0&&tx<msx&&ty<msy&&!TrMap[ty][tx])break;
  2829.             }while(z<8);
  2830.             ddr=(ddr+7)&7;
  2831.             if(z<8)Dfound=true;
  2832.         } else{
  2833.             //Turn left
  2834.             z=z>>1;
  2835.             int ddr=(Direction+8-(z&1))&7;
  2836.             int z=0;
  2837.             do{
  2838.                 dx0=idrx[ddr];
  2839.                 dy0=idry[ddr];
  2840.                 ddr=(ddr+7)&7;
  2841.                 z++;
  2842.             }while(TrMap[y+dy0][x+dx0]&&z<8);
  2843.             ddr=(ddr+1)&7;
  2844.             if(z<8)Dfound=true;
  2845.         };
  2846.         //ddr=rando()&7;
  2847.         //dx0=idrx[ddr];
  2848.         //dy0=idry[ddr];
  2849.         //ddr=(ddr+1)&7;
  2850.         //tx=x+dx0;
  2851.         //ty=y+dy0;
  2852.         if(tx>=0&&tx<msx&&ty>=0&&ty<msy)Dfound=true;
  2853.     };
  2854.     if(Dfound){
  2855.         int difR=8+ddr-Direction;
  2856.         difR&=7;
  2857.         int difL=8+Direction-ddr;
  2858.         difL&=7;
  2859.         byte minDr=difR<difL?difR:difL;
  2860.         if(int(OBJ->InLineCom))OBJ->FreeAsmLink();
  2861.         
  2862.         OBJ->LoadAnimation(0,OBJ->AnmStandKind,0);
  2863.         OBJ->LoadAnimation(1,OBJ->AnmGoKind,0);
  2864.         AddAsk(OBJ->Index,x,y,dx0,dy0);
  2865.     };
  2866.     if(OBJ->DrawUp)
  2867.         ReMemCirc(x,y);
  2868. };
  2869. void MakeExpl(int xx,int yy);
  2870. void RestoreLock(int x,int y,int lx,int ly);
  2871. void OneObject::Die(){
  2872.     if(PathX){
  2873.         free(PathX);
  2874.         free(PathY);
  2875.         PathX=NULL;
  2876.         PathY=NULL;
  2877.         NIPoints=0;
  2878.         CurIPoint=0;
  2879.     };
  2880.     GeneralObject* GO=Ref.General;
  2881.     if(!capBuilding)Nat->NGidot--;
  2882.     if(GO->DeathSound==-1){
  2883.         if(capBuilding)AddOrderEffect(x,y,Nat->BuildDieSound);
  2884.         else AddOrderEffect(x,y,Nat->UnitDieSound);
  2885.  
  2886.     }else{
  2887.         AddWarEffect(x,y,GO->DeathSound);
  2888.     };
  2889.     if(int(InLineCom))FreeAsmLink();
  2890.     do{
  2891.         if(int(LocalOrder)){
  2892.             Order1* Loc1=LocalOrder->NextOrder;
  2893.     
  2894.             FreeOrdBlock(LocalOrder);
  2895.             LocalOrder=Loc1;
  2896.         };
  2897.     }while(int(LocalOrder));
  2898.     Cell8x8* CELL=&TCInf[NNUM][y>>2][x>>2];
  2899.     CELL->UnitsAmount[Kind]--;
  2900.     if(NInside){
  2901.         for(int i=0;i<NInside;i++){
  2902.             word MID=Inside[i];
  2903.             OneObject* OB=Group[MID];
  2904.             if(OB->InLineCom)OB->FreeAsmLink();
  2905.             OB->ClearOrders();
  2906.             Group[MID]=NULL;
  2907.         };
  2908.         free(Inside);
  2909.     };
  2910.     if(OnWater){
  2911.         if(capBuilding){
  2912.             for(byte dx=0;dx<Lx;dx++)
  2913.             for(byte dy=0;dy<Ly;dy++){
  2914.                 WLock[y+dy][x+dx]=0;
  2915.                 WMap[y+dy][x+dx]=0;
  2916.                 Mops[y+dy][x+dx]=0xFFFF;
  2917.             };
  2918.         }else{
  2919.             WMap[y][x]=0;
  2920.             WLock[y][x]=0;
  2921.             Mops[y][x]=0xFFFF;
  2922.         };
  2923.     }else{
  2924.         if(Media==2){
  2925.             int cx=x>>2;
  2926.             int cy=y>>2;
  2927.             FlyCell* FC=&FlyMap[cy][cx];
  2928.             for(int pp=0;pp<15;pp++){
  2929.                 if(FC->FlyList[pp]==Index){
  2930.                     FC->FlyList[pp]=0xFFFF;
  2931.                     FC->NFly--;
  2932.                 };
  2933.             };
  2934.             MakeExpl((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  2935.             MakeExpl((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  2936.             MakeExpl((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  2937.             memset(&FlyMops[0][0],255,sizeof FlyMops);
  2938.             LoadCurAnm(2);
  2939.             TicksPerChange=1;
  2940.             Sdoxlo=true;
  2941.             Group[Index]=NULL;
  2942.             return;
  2943.         };
  2944.         RestoreLock(x,y,Lx,Lx);
  2945.         //for(byte dx=0;dx<Lx;dx++)
  2946.         //    for(byte dy=0;dy<Ly;dy++){
  2947.         //        LLock[y+dy][x+dx]=0;
  2948.         //        DecLock(x+dx,y+dy);
  2949.         //        TrMap[y+dy][x+dx]=0;
  2950.         //        Mops[y+dy][x+dx]=0xFFFF;
  2951.         //    };
  2952.     };
  2953.     if(capBuilding){
  2954.         if(Ref.General->cpbFarm&&Ready)Nat->NFarms--;
  2955.         OneObject* OO=Group[Index];
  2956.         Group[Index]=NULL;
  2957.         int n=Lx*Ly*2;
  2958.         for(int i=0;i<n;i++){
  2959.             short xx=(int(x)<<7)+(rando()>>8)*Lx;
  2960.             short yy=(int(y)<<7)+(rando()>>8)*Ly;
  2961.             CreateExObjD(WPLIST[3],xx,yy,
  2962.                  rando()&255,15,0,NULL);
  2963.         };
  2964.         //free(OO);
  2965.         return;
  2966.     };
  2967.     LoadAnimation(3,3,0);
  2968.     LoadCurAnm(3);
  2969.     Died[y][x]=Index;
  2970.     Sdoxlo=true;
  2971.     Ticks=0;
  2972.     TicksPerChange=1;
  2973. };
  2974. void OneObject::Eliminate(){
  2975.     if(int(InLineCom))FreeAsmLink();
  2976.     do{
  2977.         if(int(LocalOrder)){
  2978.             Order1* Loc1=LocalOrder->NextOrder;
  2979.             FreeOrdBlock(LocalOrder);
  2980.             LocalOrder=Loc1;
  2981.         };
  2982.     }while(int(LocalOrder));
  2983.     if(PathX){
  2984.         free(PathX);
  2985.         free(PathY);
  2986.         PathX=NULL;
  2987.         PathY=NULL;
  2988.         NIPoints=0;
  2989.         CurIPoint=0;
  2990.     };
  2991.     Cell8x8* CELL=&TCInf[NNUM][y>>2][x>>2];
  2992.     CELL->UnitsAmount[Kind]--;
  2993.     if(NInside){
  2994.         for(int i=0;i<NInside;i++){
  2995.             word MID=Inside[i];
  2996.             OneObject* OB=Group[MID];
  2997.             if(OB->InLineCom)OB->FreeAsmLink();
  2998.             OB->ClearOrders();
  2999.             Group[MID]=NULL;
  3000.         };
  3001.         free(Inside);
  3002.     };
  3003.     if(OnWater){
  3004.         if(capBuilding){
  3005.             for(byte dx=0;dx<Lx;dx++)
  3006.             for(byte dy=0;dy<Ly;dy++){
  3007.                 WLock[y+dy][x+dx]=0;
  3008.                 WMap[y+dy][x+dx]=0;
  3009.                 Mops[y+dy][x+dx]=0xFFFF;
  3010.             };
  3011.         }else{
  3012.             WMap[y][x]=1;
  3013.             WLock[y][x]=1;
  3014.             Mops[y][x]=0xFFFF;
  3015.         };
  3016.     }else
  3017.         if(Media==2){
  3018.             memset(&FlyMops[0][0],255,sizeof FlyMops);
  3019.             LoadCurAnm(2);
  3020.             TicksPerChange=1;
  3021.             Sdoxlo=true;
  3022.             return;
  3023.         };
  3024.         for(byte dx=0;dx<Lx;dx++)
  3025.             for(byte dy=0;dy<Ly;dy++){
  3026.                 LLock[y+dy][x+dx]=0;
  3027.                 DecLock(x+dx,y+dy);
  3028.                 TrMap[y+dy][x+dx]=0;
  3029.                 Mops[y+dy][x+dx]=0xFFFF;
  3030.             };
  3031.     if(capBuilding){
  3032.         if(Ref.General->cpbFarm)Nat->NFarms--;
  3033.         OneObject* OO=Group[Index];
  3034.         Group[Index]=NULL;
  3035.         //int n=Lx*Ly*2;
  3036.         //for(int i=0;i<n;i++){
  3037.         //    short xx=(int(x)<<7)+(rando()>>8)*Lx;
  3038.         //    short yy=(int(y)<<7)+(rando()>>8)*Ly;
  3039.         //    CreateExObjD(WPLIST[3],xx,yy,
  3040.         //         rando()&255,15,0,NULL);
  3041.         //};
  3042.         //free(OO);
  3043.         return;
  3044.     };
  3045.     Nat->NGidot--;
  3046.     LoadAnimation(3,3,0);
  3047.     LoadCurAnm(3);
  3048.     //Died[y][x]=Index;
  3049.     Sdoxlo=true;
  3050.     Ticks=0;
  3051.     TicksPerChange=1;
  3052.     Group[Index]=NULL;
  3053. };
  3054. void OneObject::MakeDamage(int Fundam,int Persist,OneObject* Sender){
  3055.     int shield=Ref.Visual->info.Basic.MaxShield;
  3056.     int dam=0;//Persist;
  3057.     if(Sender&&!NeedNoHelp)SearchSupport(Sender->Index);
  3058.     if(Fundam>shield)dam+=Fundam-shield;
  3059.     dam-=(dam*(tmtmt&7))>>5;
  3060.     dam+=Persist;
  3061.     if(Nat->CITY&&Sender)Nat->CITY->HelpMe(Sender->Index);
  3062.     if(!Nat->LastAttackTime){
  3063.         Nat->LastAttackTime=100;
  3064.         if(NNUM==MyNation&&dam>0)AddTEffect(x,y,Nat->DangerSound);
  3065.     };
  3066.     if(dam<=0)return;
  3067.     if(Life>dam)Life-=dam;else{
  3068.         if(Sender)InFire=Sender->Ref.General->FWEAP;
  3069.         else InFire=true;
  3070.         Life=0;
  3071.         return;
  3072.     };
  3073.     if(!int(Sender)||Sender==this||Egoist)return;
  3074.     if(!NoAnswer)AttackObj(Sender->Index,1);
  3075. };
  3076. void OneObject::SearchSupport(word OBJ){
  3077.     if(Egoist)return;
  3078.     word MID;
  3079.     char dx;
  3080.     char dy;
  3081.     byte MyMsk=NMask;
  3082.     int x0=x-6;
  3083.     int y0=y-6;
  3084.     int x1=x+6;
  3085.     int y1=y+6;
  3086.     if(x0<1)x0=1;
  3087.     if(y0<1)y0=1;
  3088.     if(x1>=msx)x1=msx-1;
  3089.     if(y1>=msy)y1=msy-1;
  3090.     for(int xx=x0;xx<=x1;xx++)
  3091.         for(int yy=y0;yy<=y1;yy++){
  3092.             MID=Mops[yy][xx];
  3093.             if(MID!=0xFFFF){
  3094.                 OneObject* OO=Group[MID];
  3095.                 if(OO->NMask&MyMsk){//±ΓεΘ!
  3096.                     //ταφ ≥?
  3097.                     if(!OO->NoAnswer)
  3098.                         OO->AttackObj(OBJ,0);
  3099.                 };
  3100.             };
  3101.         };
  3102.     return;
  3103.  
  3104.  
  3105.     for(int j=0;j<8;j++){
  3106.         x1=x+idrx[j];
  3107.         y1=y+idry[j];
  3108.         MID=Mops[y1][x1];
  3109.         if(MID!=0xFFFF){
  3110.             OneObject* OO=Group[MID];
  3111.             if(OO->NMask&MyMsk){//±ΓεΘ!
  3112.                 //ταφ ≥?
  3113.                 if(!OO->NoAnswer)
  3114.                     OO->AttackObj(OBJ,0);
  3115.             };
  3116.         };
  3117.     };
  3118.     for(j=0;j<8;j++){
  3119.         dx=(rando()&15)-7;
  3120.         dy=(rando()&15)-7;
  3121.         x1=x+dx;
  3122.         y1=y+dy;
  3123.         if(x1>0&&y1>0&&x1<msx&&y1<msy){
  3124.             MID=Mops[y1][x1];
  3125.             if(MID!=0xFFFF){
  3126.                 OneObject* OO=Group[MID];
  3127.                 if(OO->NMask&MyMsk){//±ΓεΘ!
  3128.                     //ταφ ≥?
  3129.                     if(!OO->NoAnswer)
  3130.                         OO->AttackObj(OBJ,0);
  3131.                     //else if(!(rando()&3))OO->AttackObj(OBJ,1);
  3132.                 };
  3133.             };
  3134.         };
  3135.     };
  3136. };
  3137. word FindTerrEnemy(int xCell,int yCell,int mx,int my,int dist,byte Mask){
  3138.     int dst=500;
  3139.     int dista;
  3140.     word BMID=0xFFFF;
  3141.     word MID;
  3142.     int xx=xCell<<2;
  3143.     int yy=yCell<<2;
  3144.     for(int x=0;x<4;x++)
  3145.         for(int y=0;y<4;y++){
  3146.             MID=Mops[yy+y][xx+x];
  3147.             if(MID!=0xFFFF){
  3148.                 OneObject* OB=Group[MID];
  3149.                 if(OB&&!(OB->NMask&Mask)){
  3150.                     dista=OB->DistTo(mx,my);
  3151.                     if(dista<dst&&dista<dist){
  3152.                         BMID=MID;
  3153.                         dst=dista;
  3154.                     };
  3155.                 };
  3156.             };
  3157.         };
  3158.     return BMID;
  3159. };
  3160. word FindAirEnemy(int xCell,int yCell,int mx,int my,int dist,byte Mask){
  3161.     int dst=500;
  3162.     int dista;
  3163.     word BMID=0xFFFF;
  3164.     word MID;
  3165.     FlyCell* FC=&FlyMap[yCell][xCell];
  3166.     if(!FC->NFly)return 0xFFFF;
  3167.     for(int p=0;p<15;p++){
  3168.         MID=FC->FlyList[p];
  3169.         if(MID!=0xFFFF){
  3170.             OneObject* OB=Group[MID];
  3171.             if(OB&&!(OB->NMask&Mask)){
  3172.                 dista=OB->DistTo(mx,my);
  3173.                 if(dista<dst&&dista<dist){
  3174.                     BMID=MID;
  3175.                     dst=dista;
  3176.                 };
  3177.             };
  3178.         };
  3179.     };
  3180.     return BMID;
  3181. };
  3182. /*void OneObject::SearchVictim(){
  3183.     if(Egoist)return;
  3184.     byte x1;
  3185.     byte y1;
  3186.     word MID;
  3187.     char dx;
  3188.     char dy;
  3189.     byte MyMsk=NMask;
  3190.     for(int j=0;j<8;j++){
  3191.         x1=x+idrx[j];
  3192.         y1=y+idry[j];
  3193.         MID=Mops[y1][x1];
  3194.         if(MID!=0xFFFF){
  3195.             OneObject* OO=Group[MID];
  3196.             if(!(OO->NMask&MyMsk))//Γ≡απ!
  3197.                 AttackObj(MID,2);
  3198.         };
  3199.     };
  3200.     char LXR=(VisRadius<<1)+1;
  3201.     char VR=VisRadius;
  3202.     char NR=VisSpots;
  3203.     for(j=0;j<NR;j++){
  3204.         dx=char(RNTB[LXR][rando()&255])-VR;
  3205.         dy=char(RNTB[LXR][rando()&255])-VR;
  3206.         x1=x+dx;
  3207.         y1=y+dy;
  3208.         if(x1>0&&y1>0&&x1<msx&&y1<msy){
  3209.             MID=Mops[y1][x1];
  3210.             if(MID!=0xFFFF){
  3211.                 OneObject* OO=Group[MID];
  3212.                 if(!(OO->NMask&MyMsk))//Γ≡απ
  3213.                         AttackObj(MID,2);
  3214.             };
  3215.         };
  3216.     };
  3217. };*/
  3218. void OneObject::SearchVictim(){
  3219.     if(Egoist)return;
  3220.     //check neighbor
  3221.     int xc=x>>2;
  3222.     int yc=y>>2;
  3223.     char VR=Ref.Visual->info.Basic.AttackRange;
  3224.     if((!capBuilding)&&VR<5)VR=5;
  3225.     word MID;
  3226.     byte EnMask=~NMask;
  3227.     if(NPresence[yc][xc]&EnMask){
  3228.         MID=FindTerrEnemy(xc,yc,x,y,VR,NMask);
  3229.         if(MID==0xFFFF)
  3230.             MID=FindAirEnemy(xc,yc,x,y,VR,NMask);
  3231.         if(MID!=0xFFFF){
  3232.             AttackObj(MID,6);
  3233.             return;
  3234.         };
  3235.     };
  3236.     //check remote neighbor
  3237.     char LXR=((VR>>1)&254);
  3238.     int VR1=VR>>2;
  3239.     int x0;
  3240.     int y0;
  3241.     int x1;
  3242.     int y1;
  3243.     int dx;
  3244.     int dy;
  3245.     byte MyMsk=NMask;
  3246.     char NR=VisSpots;
  3247.     for(int j=0;j<NR;j++){
  3248.         dx=char(RNTB[LXR][rando()&255])-VR1;
  3249.         dy=char(RNTB[LXR][rando()&255])-VR1;
  3250.         x0=xc+dx;
  3251.         y0=yc+dy;
  3252.         if(x0>0&&y0>0&&x0<64&&y0<64&&NPresence[y0][x0]&EnMask){
  3253.             MID=FindTerrEnemy(x0,y0,x,y,VR,NMask);
  3254.             if(MID==0xFFFF)MID=FindAirEnemy(x0,y0,x,y,VR,NMask);
  3255.             if(MID!=0xFFFF){
  3256.                 AttackObj(MID,6);
  3257.                 return;
  3258.             };
  3259.         };
  3260.     };
  3261. };
  3262. void WinnerControl(){
  3263.     if(!(tmtmt&15)){
  3264.         NMyUnits=0;
  3265.         NThemUnits=0;
  3266.         for(int i=0;i<MAXOBJECT;i++){
  3267.             OneObject* OB=Group[i];
  3268.             if(OB&&!OB->Ref.General->UFO){
  3269.                 if(OB->NNUM==MyNation)NMyUnits++;
  3270.             else NThemUnits++;
  3271.             };
  3272.         };
  3273.     };
  3274. };
  3275. void OneObject::DefaultSettings(GeneralObject* GO){
  3276.     Ustage=0;
  3277.     NUstages=0;
  3278.     Magic=0;
  3279.     capMagic=GO->capMagic;
  3280.     xForce=16;
  3281.     //DoubleForce=false;
  3282.     //TripleForce=false;
  3283.     //QuadraForce=false;
  3284.     MTime=0;
  3285.     NInside=0;
  3286.     Transport=GO->Transport;
  3287.     if(Transport)Inside=new word[18];
  3288.     else Inside=NULL;
  3289.     TimeInside=NULL;
  3290.     Serial=rando();
  3291.     Absent=false;
  3292.     Slow=false;
  3293.     Invisible=false;
  3294.     InFire=false;
  3295.     AbRes=0;
  3296.     MagSrcID=0xFFFF;
  3297.     if(GO->AGold)AbRes|=2;
  3298.     if(GO->AWood)AbRes|=4;
  3299.     RefreshLife=GO->RefreshLife;
  3300.     DoWalls=false;
  3301.     Use_AI=false;
  3302.     AntiNuc=GO->AntiNuc;
  3303.     if(AntiNuc){
  3304.         RAmount=1;
  3305.         delay=3000;
  3306.     }else RAmount=0;
  3307.     UFOTrans=GO->UFOTrans;
  3308.     DstX=0;
  3309.     DstY=0;
  3310.     capBuilding=GO->cpbBuilding;
  3311.     Repair=false;
  3312.     PathX=NULL;
  3313.     PathY=NULL;
  3314.     NIPoints=0;
  3315.     CurIPoint=0;
  3316.     CPdestX=0;
  3317.     CPdestY=0;
  3318. };
  3319. void PatrolLink(OneObject* OBJ);
  3320. void OneObject::Patrol(int x,int y,int x1,int y1,byte Prio){
  3321.     if(Prio<PrioryLevel)return;
  3322.     if(!Ready)return;
  3323.     if(!(cpbMoving))return;
  3324.     Order1* Or1=GetOrdBlock();
  3325.     if(!int(Or1))return;
  3326.     Or1->PrioryLevel=Prio&127;
  3327.     Or1->NextOrder=LocalOrder;
  3328.     Or1->OrderType=81;//└≥αΩα
  3329.     Or1->OrderTime=0;
  3330.     Or1->DoLink=&PatrolLink;
  3331.     Or1->info.Patrol.x=x;
  3332.     Or1->info.Patrol.y=y;
  3333.     Or1->info.Patrol.x1=x1;
  3334.     Or1->info.Patrol.y1=y1;
  3335.     Or1->info.Patrol.dir=1;
  3336.     Order1* LOR=LocalOrder;
  3337.     if(int(InLineCom))FreeAsmLink();
  3338.     LocalOrder=Or1;
  3339.     PrioryLevel=Prio&127;
  3340.     //OrderReport=NULL;
  3341.     //MessageKind=0;
  3342.     //Sender=0xFFFF;
  3343. };    
  3344. void PatrolLink(OneObject* OBJ){
  3345.     byte x=OBJ->LocalOrder->info.Patrol.x;
  3346.     byte y=OBJ->LocalOrder->info.Patrol.y;
  3347.     byte x1=OBJ->LocalOrder->info.Patrol.x1;
  3348.     byte y1=OBJ->LocalOrder->info.Patrol.y1;
  3349.     byte dir=OBJ->LocalOrder->info.Patrol.dir;
  3350.     OBJ->ClearOrders();
  3351.     if(OBJ->InLineCom)OBJ->FreeAsmLink();
  3352.     OBJ->PrioryLevel=0;
  3353.     if(dir)OBJ->SendTo(x1,y1,0);
  3354.     else OBJ->SendTo(x,y,0);
  3355.     Order1* OR1=OBJ->LocalOrder;
  3356.     if(OR1){
  3357.         Order1* OR2=GetOrdBlock();
  3358.         if(OR2){
  3359.             OR1->NextOrder=OR2;
  3360.             OR2->info.Patrol.x=x;
  3361.             OR2->info.Patrol.y=y;
  3362.             OR2->info.Patrol.x1=x1;
  3363.             OR2->info.Patrol.y1=y1;
  3364.             OR2->info.Patrol.dir=!dir;
  3365.             OR2->DoLink=&PatrolLink;
  3366.             OR2->OrderType=81;
  3367.             OR2->NextOrder=NULL;
  3368.         };
  3369.     };
  3370. };
  3371. void OneObject::EnableDoubleForce(){
  3372.  
  3373. };
  3374. void OneObject::DisableDoubleForce(){
  3375. };
  3376. void OneObject::EnableTripleForce(){
  3377. };
  3378. void OneObject::DiasableTripleForce(){
  3379. };
  3380. void OneObject::EnableQuadraForce(){
  3381. };
  3382. void OneObject::DisableQuadraForce(){
  3383. };
  3384. void WaitForRepairLink(OneObject* OBJ);
  3385. void OneObject::WaitForRepair(){
  3386.     if(!Ref.General->CanRepair)return;
  3387.     Order1* Or1=GetOrdBlock();
  3388.     if(!int(Or1))return;
  3389.     Or1->PrioryLevel=0;
  3390.     Or1->NextOrder=LocalOrder;
  3391.     Or1->OrderType=103;//└≥αΩα
  3392.     Or1->OrderTime=0;
  3393.     Or1->DoLink=&WaitForRepairLink;
  3394.     Or1->info.MoveToXY.x=x;
  3395.     Or1->info.MoveToXY.y=y;
  3396.     PrioryLevel=0;
  3397.     LocalOrder=Or1;
  3398. };
  3399. void WaitForRepairLink(OneObject* OBJ){
  3400.     if(!OBJ->Repair){
  3401.         Order1* LO1=OBJ->LocalOrder;
  3402.         OBJ->LocalOrder=LO1->NextOrder;
  3403.         OBJ->FreeOrdBlock(LO1);
  3404.         return;
  3405.     };
  3406.     int xx=OBJ->x;
  3407.     int yy=OBJ->y;
  3408.     int xxx,yyy;
  3409.     for(int i=0;i<4;i++){
  3410.         xxx=xx+(rando()&15)-8;
  3411.         yyy=yy+(rando()&15)-8;
  3412.         if(xxx>1&&yyy>1&&xxx<msx&&yy<msy){
  3413.             word MID=Mops[yyy][xxx];
  3414.             if(MID!=0xFFFF){
  3415.                 OneObject* OB=Group[MID];
  3416.                 if(OB&&OB->capBuilding&&OB->Life<OB->MaxLife){
  3417.                     if(!OB->capTeleport)OBJ->BuildObj(OB->Index,16);
  3418.                 return;
  3419.                 };
  3420.             };
  3421.         };
  3422.     };
  3423.     xx=OBJ->LocalOrder->info.MoveToXY.x;
  3424.     yy=OBJ->LocalOrder->info.MoveToXY.y;
  3425.     if(rando()<4000&&(xx!=OBJ->x||yy!=OBJ->y))OBJ->SendTo(xx,yy,0);
  3426. };
  3427. //####################################################//
  3428. //################                 ###################//
  3429. //##############   NUCLEAR SECTION   #################//
  3430. //################                 ###################//
  3431. //####################################################//
  3432. extern bool EUsage[8192];
  3433. extern word LastAnmIndex;
  3434. extern AnmObject* GAnm[8192];
  3435. word NucList[128];
  3436. word NucSN[128];
  3437. bool NDone[128];
  3438. word NNuc;
  3439. void InitNucList(){
  3440.     memset(NucList,255,sizeof NucList);
  3441.     memset(NucSN,255,sizeof NucSN);
  3442.     NNuc=0;
  3443. };
  3444. void RegisterNuc(word ID){
  3445.     if(!EUsage[ID])return;
  3446.     for(int i=0;i<128;i++){
  3447.         if(NucList[i]==0xFFFF){
  3448.             NucList[i]=ID;
  3449.             NucSN[i]=GAnm[ID]->ASerial;
  3450.             NDone[i]=false;
  3451.             NNuc++;
  3452.             return;
  3453.         };
  3454.     };
  3455. };
  3456. void HandleAntiNuc(){
  3457.     if(!NNuc)return;
  3458.     for(int i=0;i<128;i++){
  3459.         if(NucList[i]!=0xFFFF){
  3460.             if(!EUsage[NucList[i]]){
  3461.                 NucList[i]=0xFFFF;
  3462.                 NNuc--;
  3463.             }else{
  3464.                 AnmObject* EO=GAnm[NucList[i]];
  3465.                 if(EO->ASerial!=NucSN[i]){
  3466.                     NucList[i]=0xFFFF;
  3467.                     NNuc--;
  3468.                 }else
  3469.                 if(!NDone[i]){
  3470.                     byte NMS=EO->NMask;
  3471.                     int dpx=EO->destX;
  3472.                     int dpy=EO->destY;
  3473.                     word AID=0xFFFF;
  3474.                     int adist=1000;
  3475.                     int diss;
  3476.                     //find nearest enemy antinuclear;
  3477.                     for(int j=0;j<MAXOBJECT;j++){
  3478.                         OneObject* OB=Group[j];
  3479.                         if(OB&&OB->RAmount&&OB->AntiNuc&&!(OB->NMask&NMS)){
  3480.                             diss=abs(dpx-int(OB->x))+abs(dpy-int(OB->y));
  3481.                             if(diss<adist){
  3482.                                 AID=j;
  3483.                                 adist=diss;
  3484.                             };
  3485.                         };
  3486.                     };
  3487.                     if(AID!=0xFFFF){
  3488.                         OneObject* OB=Group[AID];
  3489.                         OB->RAmount--;
  3490.                         CreateLeadingObject(OB->Weap,((OB->x<<5)+OB->wepX)<<2,((OB->y<<5)+OB->wepY)<<2,128,OB->NMask,OB,NucList[i]);
  3491.                         NDone[i]=true;
  3492.                     };
  3493.                 };
  3494.             };
  3495.         };
  3496.     };
  3497. };
  3498. void ShowNucl(){
  3499.     if(!NNuc)return;
  3500.     for(int i=0;i<128;i++){
  3501.         if(NucList[i]!=0xFFFF){
  3502.             AnmObject* EO=GAnm[NucList[i]];
  3503.             int xx=minix+(EO->x>>16);
  3504.             int yy=miniy+(EO->y>>16);
  3505.             Hline(xx-1,yy,xx+1,255);
  3506.             Vline(xx,yy-1,yy+1,255);
  3507.             xx=minix+(EO->destX>>1);
  3508.             yy=minix+(EO->destY>>1);
  3509.             Hline(xx-2,yy,xx-1,clrYello);
  3510.             Hline(xx+1,yy,xx+2,clrYello);
  3511.             Vline(xx,yy-2,yy-1,clrYello);
  3512.             Vline(xx,yy+1,yy+2,clrYello);
  3513.         };
  3514.     };
  3515. };
  3516. void NuclearAttackLink(OneObject* OB);
  3517. void OneObject::NuclearAttack(byte x,byte y){
  3518.     if(delay)return;
  3519.     if(!Ref.General->canNucAttack)return;
  3520.     ClearOrders();
  3521.     Order1* Or1=GetOrdBlock();
  3522.     if(!int(Or1))return;
  3523.     Or1->PrioryLevel=120;
  3524.     Or1->NextOrder=NULL;
  3525.     Or1->OrderType=200;
  3526.     Or1->OrderTime=0;
  3527.     Or1->DoLink=&NuclearAttackLink;
  3528.     Or1->info.MoveToXY.x=x;
  3529.     Or1->info.MoveToXY.y=y;
  3530.     Or1->info.MoveToXY.Times=0;//stage
  3531.     Or1->info.MoveToXY.PrevDist=0;//animation
  3532.     LocalOrder=Or1;
  3533.     LoadAnimation(1,4,0);
  3534.     LoadCurAnm(1);
  3535.     PrioryLevel=120;
  3536. };
  3537. void NuclearAttackLink(OneObject* OB){
  3538.     word anm=OB->LocalOrder->info.MoveToXY.PrevDist;
  3539.     byte stag=OB->LocalOrder->info.MoveToXY.Times;
  3540.     int x=OB->LocalOrder->info.MoveToXY.x;
  3541.     int y=OB->LocalOrder->info.MoveToXY.y;
  3542.     OB->LocalOrder->info.MoveToXY.PrevDist++;
  3543.     if(!stag){
  3544.         //Opening the can
  3545.         int csp=OB->CurrentSprite;
  3546.         if(csp<OB->CurAnm->count-1){
  3547.             OB->CurrentSprite=anm>>4;    
  3548.         }else OB->LocalOrder->info.MoveToXY.Times=1;
  3549.     }else{
  3550.         CreateStrangeObject(11,OB->NNUM,OB->x+1,OB->y+1,0xFFFF);
  3551.         OB->Ref.Visual->info.Basic.AttackRange=250;
  3552.         CreateUniExObj(OB->Weap,((OB->x<<5)+OB->wepX)<<2,((OB->y<<5)+OB->wepY)<<2,OB->Ref.General->WepSpeed,OB->NMask,OB,x,y,OB->Index);
  3553.         if(LastAnmIndex!=-1)RegisterNuc(LastAnmIndex);
  3554.         OB->Ref.Visual->info.Basic.AttackRange=0;
  3555.         OB->ClearOrders();
  3556.         OB->LoadAnimation(0,0,0);
  3557.         OB->LoadCurAnm(0);
  3558.         OB->delay=5000;
  3559.     };
  3560. };
  3561. //**************************************************//
  3562. //                                                  //
  3563. //            INITIALISATION OF THE GAME            //
  3564. //                                                  //
  3565. //**************************************************//
  3566. void InitGame(){
  3567.     InitNucList();
  3568. };