home *** CD-ROM | disk | FTP | other *** search
/ WarCraft 2000 - Nuclear Epidemic / W2000.nrg / SOURCE.War2000 / FlyObj.cpp < prev    next >
C/C++ Source or Header  |  1998-09-25  |  36KB  |  1,503 lines

  1. #include "ddini.h"
  2. #include "ResFile.h"
  3. #include "FastDraw.h"
  4. #include "mgraph.h"
  5. #include "mouse.h"
  6. #include "menu.h"
  7. #include "MapDiscr.h"
  8. #include "multipl.h"
  9. #include "fog.h"
  10. #include "walls.h"
  11. #include "Nature.h"
  12. #include "Nucl.h"
  13. #include "TopZones.h"
  14. #include "Megapolis.h"
  15. #include "FlyObj.h"
  16. #include "assert.h"
  17. #include "Mode.h"
  18. #include "GSound.h"
  19. extern byte Quality;
  20. typedef  bool CHOBJ(OneObject* OB,int N);
  21. int MyHeight;
  22. extern word FlyMops[256][256];
  23. void FlyCell::GetForces(int x,int y,int *Fx,int *Fy,word MD){
  24.     if(!NFly){
  25.         *Fx=0;
  26.         *Fy=0;
  27.         return;
  28.     };
  29.     word MID;
  30.     int Frx=0;
  31.     int Fry=0;
  32.     for(int i=0;i<15;i++){
  33.         MID=FlyList[i];
  34.         if(MID!=0xFFFF&&MID!=MD){
  35.             OneObject* OB=Group[MID];
  36.             if(OB&&OB->Media==2){
  37.                 if(abs(int(OB->Height)-MyHeight)<8){
  38.                     int xx=OB->RealX;
  39.                     int yy=OB->RealY;
  40.                     while(xx==x&&yy==y){
  41.                         xx+=3;//int(rando()&7)-3;
  42.                         yy+=3;//int(rando()&7)-3;
  43.                     };
  44.                     int dist=abs(x-xx)+abs(y-yy);
  45.                     if(dist<(16*85)){
  46.                         //ottalkivanie
  47.                         if(dist){
  48.                             Frx+=div((x-xx)<<5,dist).quot;
  49.                             Fry+=div((y-yy)<<5,dist).quot;
  50.                         };
  51.                     };
  52.                 };
  53.             };
  54.         };
  55.     };
  56.     *Fx=Frx;
  57.     *Fy=Fry;
  58.     return;
  59. };
  60. FlyCell::FlyCell(){
  61.     NFly=0;
  62.     memset(FlyList,255,sizeof FlyList);
  63. };
  64. FlyCell FlyMap[64][64];
  65. extern word LastObject;
  66. bool Nation::CreateOnFly(int x,int y,int n){
  67.     int cx=x>>2;
  68.     int cy=y>>2;
  69.     FlyCell* FC=&FlyMap[cy][cx];
  70.     if(FC->NFly>=15)return false;
  71.     int Rex=(x<<9)+256;
  72.     int Rey=(y<<9)+256;
  73.     for(int i=0;i<MaxObj&&int(Group[i]);i++);
  74.     if(i>MaxObj)return false;
  75.     if(n>=NMon) return false;
  76.     if(i>=MAXOBJECT)MAXOBJECT=i+1;
  77.     for(int k=0;FC->FlyList[k]!=0xFFFF;k++);
  78.     FC->NFly++;
  79.     FC->FlyList[k]=i;
  80.     Group[i]=OBJECTS+i;
  81.     LastObject=i;
  82.     Cell8x8* CELL=&TCInf[NNUM][y>>2][x>>2];
  83.     OneObject* G=Group[i];
  84.     GeneralObject* GO=Mon[n];
  85.     AddOrderEffect(x,y,GO->BornSound);
  86.     CELL->UnitsAmount[GO->Kind]++;
  87.     G->DefaultSettings(GO);
  88.     G->Teleport=false;
  89.     G->capTeleport=GO->Teleport;
  90.     G->RealX=Rex;
  91.     G->RealY=Rey;
  92.     G->DestX=Rex;
  93.     G->DestY=Rey;
  94.     G->RealVx=0;
  95.     G->RealVy=0;
  96.     G->RealDir=rando()&255;
  97.     G->Media=2;
  98.     G->OnWater=false;
  99.     G->Kind=GO->Kind;
  100.     G->VisRadius=GO->VisRadius;
  101.     G->VisSpots=GO->VisSpots;
  102.     G->SpotType=GO->SpotType;
  103.     G->SpotSize=GO->SpotSize;
  104.     G->DangerZone=GO->DangerZone;
  105.     G->NoSearchVictim=GO->NoSearchVictim;
  106.     G->NoAnswer=GO->NoAnswer;
  107.     G->NeedNoHelp=GO->NeedNoHelp;
  108.     G->Nat=this;
  109.     G->Ready=true;
  110.     G->wepX=GO->wepX;
  111.     G->wepY=GO->wepY;
  112.     G->MaxDelay=GO->delay;
  113.     G->delay=0;
  114.     G->NearBase=0xFFFF;
  115.     G->capBase=GO->cpbBase;
  116.     G->RStage=0;
  117.     G->RType=0;
  118.     G->RAmount=0;
  119.     G->NNUM=NNUM;
  120.     G->NIndex=n;
  121.     G->AnmStandKind=0;
  122.     G->AnmGoKind=1;
  123.     G->capBuild=GO->cpbBuild;
  124.     G->GroupIndex=NULL;
  125.     G->cpbMoving=GO->cpbMoving;
  126.     if(!GO->SizeX)GO->SizeX=1;
  127.     if(!GO->SizeY)GO->SizeY=1;
  128.     G->Lx=GO->SizeX;
  129.     G->Ly=GO->SizeY;
  130.     G->TempFlag=false;
  131.     G->Mobilised=false;
  132.     G->Wars=NULL;
  133.     G->Index=i;
  134.     //Mops[y][x]=i;
  135.     Visuals* m;
  136.     m=(Visuals*)Mon[n];
  137.     G->Selected=false;
  138.     G->Borg=false;
  139.     G->Life=m->info.Basic.MaxLife;
  140.     G->MaxLife=m->info.Basic.MaxLife;
  141.     G->Ref.Visual=m;
  142.     G->x=x;
  143.     G->y=y;
  144.     G->CrowdRef=NULL;
  145.     G->Push=false;
  146.     //LLock[y][x]=true;
  147.     //IncLock(x,y);
  148.     G->Direction=rando() & 7;
  149.     memset(&(G->ARegs),0,sizeof G->ARegs);
  150.     G->LoadAnimation(0,0,0);
  151.     G->LoadCurAnm(0);
  152.     G->LocalOrder=NULL;
  153.     //G->OrderReport=NULL;
  154.     //G->MessageFlags=0;
  155.     G->PrioryLevel=0;
  156.     //G->MessageKind=0;
  157.     G->InLineCom=NULL;
  158.     G->LineOffset=0;
  159.     G->Ticks=0;
  160.     G->TicksPerChange=10;
  161.     G->Wait=0;
  162.     G->Addx=0;
  163.     G->Addy=0;
  164. //    G->inMotion=false;
  165.     G->Npush=0;
  166.     G->StandTime=100;
  167.     G->Sdoxlo=false;
  168.     G->Weap=Mon[n]->Weap;
  169.     G->NMask=NMask;
  170.     G->Important=false;
  171.     G->EnemyDist=5000;
  172.     G->Attack=false;
  173.     G->EnemyID=0xFFFF;
  174.     G->Egoist=false;
  175.     G->Height=0;
  176.     G->LoadAnimation(0,0,0);//stand=motion animation
  177.     G->LoadAnimation(1,2,0);//attack
  178.     G->LoadAnimation(2,3,0);//death
  179.     G->BestDist=32*16*6;
  180.     G->FlyAttackMode=false;
  181.     NGidot++;
  182.     if(GO->UFO)G->MakeMeUFO();
  183.     return true;
  184. };
  185. void OneObject::MakeMeFly(word MagID){
  186.     if(MagID==0xFFFF||Media==2)return;
  187.     if(!Ref.General->CanFly)return;
  188.     MagSrcID=MagID;
  189.     int cx=x>>2;
  190.     int cy=y>>2;
  191.     ClearOrders();
  192.     if(InLineCom)FreeAsmLink();
  193.     FlyCell* FC=&FlyMap[cy][cx];
  194.     if(FC->NFly>=15)return;
  195.     //Deleting from the terra
  196.     if(LLock[y][x])DecLock(x,y);
  197.     LLock[y][x]=0;
  198.     Mops[y][x]=0xFFFF;
  199.     int Rex=(x<<9)+256;
  200.     int Rey=(y<<9)+256;
  201.     for(int k=0;FC->FlyList[k]!=0xFFFF;k++);
  202.     FC->NFly++;
  203.     FC->FlyList[k]=Index;
  204.     //Cell8x8* CELL=&TCInf[NNUM][y>>2][x>>2];
  205.     //OneObject* G=Group[i];
  206.     //GeneralObject* GO=Mon[n];
  207.     //CELL->UnitsAmount[GO->Kind]++;
  208.     //G->DefaultSettings(GO);
  209.     //G->Teleport=false;
  210.     //G->capTeleport=GO->Teleport;
  211.     RealX=Rex;
  212.     RealY=Rey;
  213.     DestX=Rex;
  214.     DestY=Rey;
  215.     RealVx=0;
  216.     RealVy=-128;
  217.     RealDir=((Direction<<5)+16)&255;
  218.     Media=2;
  219.     OnWater=false;
  220.     Ready=true;
  221.     delay=0;
  222.     NearBase=0xFFFF;
  223.     memset(&(ARegs),0,sizeof ARegs);
  224.     LoadAnimation(0,0,0);
  225.     LoadCurAnm(0);
  226.     LocalOrder=NULL;
  227.     PrioryLevel=0;
  228.     InLineCom=NULL;
  229.     LineOffset=0;
  230.     Ticks=0;
  231.     Addx=0;
  232.     Addy=0;
  233.     Npush=0;
  234.     StandTime=100;
  235.     Sdoxlo=false;
  236.     EnemyDist=5000;
  237.     Attack=false;
  238.     EnemyID=0xFFFF;
  239.     Egoist=false;
  240.     Height=0;
  241.     LoadAnimation(0,0,0);//stand=motion animation
  242.     LoadAnimation(1,2,0);//attack
  243.     LoadAnimation(2,3,0);//death
  244.     BestDist=32*16*6;
  245.     FlyAttackMode=false;
  246. };
  247. void MakeFog(int xx,int yy);
  248. void OneObject::MakeMeSit(){
  249.     if(!(Media==2&&Ref.General->CanFly))return;
  250.     MakeFog((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  251.     MakeFog((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  252.     MakeFog((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  253.     //MakeFog((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  254.     //MakeFog((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  255.     MakeFog((RealX>>2)+(rando()&255)-128,(RealY>>2)+(rando()&255)-128);
  256.     if(LLock[y][x]){
  257.         Die();
  258.         return;
  259.     };
  260.     ClearOrders();
  261.     if(InLineCom)FreeAsmLink();
  262.     int cx=x>>2;
  263.     int cy=y>>2;
  264.     FlyCell* FC=&FlyMap[cy][cx];
  265.     for(int pp=0;pp<15;pp++){
  266.         if(FC->FlyList[pp]==Index){
  267.             FC->FlyList[pp]=0xFFFF;
  268.             FC->NFly--;
  269.         };
  270.     };
  271.     Media=0;
  272.     FlyMops[y][x]=0xFFFF;
  273.     Mops[y][x]=Index;
  274. };
  275. void OneObject::ProcessMotion(){
  276.     int cx=(RealX-256)>>11;
  277.     int cy=(RealY-256)>>11;
  278.     int mx=msx>>2;
  279.     int my=msy>>2;
  280.     if(cx<0){
  281.         RealX=256+512;
  282.         cx=0;
  283.     };
  284.     if(cy<0){
  285.         RealY=256+512;
  286.         cy=0;
  287.     };
  288.     if(cx>=mx){
  289.         RealX=(msx<<9)-256;
  290.         cx=mx;
  291.     };
  292.     if(cy>=my){
  293.         RealY=(msy<<9)-256;
  294.         cy=my;
  295.     };
  296.     int Fx=0;
  297.     int Fy=0;
  298.     int dfx;
  299.     int dfy;
  300.     MyHeight=Height;
  301.     FlyCell* FC=&FlyMap[cy][cx];
  302.     FC->GetForces(RealX,RealY,&dfx,&dfy,Index);
  303.     Fx+=dfx;
  304.     Fy+=dfy;
  305.     if(cx>0){
  306.         FC[-1].GetForces(RealX,RealY,&dfx,&dfy,Index);
  307.         Fx+=dfx;
  308.         Fy+=dfy;
  309.     };
  310.     if(cy>0){
  311.         FC[-64].GetForces(RealX,RealY,&dfx,&dfy,Index);
  312.         Fx+=dfx;
  313.         Fy+=dfy;
  314.     };
  315.     if(cx<=mx){
  316.         FC[1].GetForces(RealX,RealY,&dfx,&dfy,Index);
  317.         Fx+=dfx;
  318.         Fy+=dfy;
  319.     };
  320.     if(cy<=my){
  321.         FC[64].GetForces(RealX,RealY,&dfx,&dfy,Index);
  322.         Fx+=dfx;
  323.         Fy+=dfy;
  324.     };
  325.     int rdx=DestX-RealX;
  326.     int rdy=DestY-RealY;
  327.     int ard=abs(rdx)+abs(rdy);
  328.     if(ard<128){
  329.         rdx=0;
  330.         rdy=0;
  331.     };
  332.     if(ard>256){
  333.         rdx=div(rdx<<8,ard).quot;
  334.         rdy=div(rdy<<8,ard).quot;
  335.     };
  336.     Fx+=rdx>>3;
  337.     Fy+=rdy>>3;
  338.     int af=abs(Fx)+abs(Fy);
  339.     if(af>32){
  340.         Fx=div(Fx<<5,af).quot;
  341.         Fy=div(Fy<<5,af).quot;
  342.     };
  343.     int ax=-(RealVx>>3)+Fx;
  344.     int ay=-(RealVy>>3)+Fy;
  345.     ard=abs(ax)+abs(ay);
  346.     if(ard>32){
  347.         ax=div(ax<<5,ard).quot;
  348.         ay=div(ay<<5,ard).quot;
  349.     };
  350.     RealVx+=ax;
  351.     RealVy+=ay;
  352.     if((!(ax||ay))&&(abs(RealVx)<8&&abs(RealVy<8))){
  353.         RealVx=0;
  354.         RealVy=0;
  355.     };
  356.     /*ard=sqrt((RealVx*RealVx)+(RealVy*RealVy));
  357.     if(ard>MaxSpeed){
  358.         RealVx=div(RealVx*MaxSpeed,ard).quot;
  359.         RealVy=div(RealVy*MaxSpeed,ard).quot;
  360.     };*/
  361.     int rxx=RealX;
  362.     int ryy=RealY;
  363.     RealX+=RealVx;
  364.     RealY+=RealVy;
  365.     int ocx=cx;
  366.     int ocy=cy;
  367.     cx=(RealX-256)>>11;
  368.     cy=(RealY-256)>>11;
  369.     if(cx<0){
  370.         RealX=256+512;
  371.         cx=0;
  372.     };
  373.     if(cy<0){
  374.         RealY=256+512;
  375.         cy=0;
  376.     };
  377.     if(cx>=mx){
  378.         RealX=(msx<<9)-256;
  379.         cx=mx-1;
  380.     };
  381.     if(cy>=my){
  382.         RealY=(msy<<9)-256;
  383.         cy=my-1;
  384.     };
  385.     if(ocx!=cx||ocy!=cy){
  386.         FlyCell* FC1=&FlyMap[cy][cx];
  387.         if(FC1->NFly>=15){
  388.             RealX=rxx;
  389.             RealY=ryy;
  390.         }else{
  391.             word MD=Index;
  392.             for(int p=0;p<15;p++)
  393.                 if(FC->FlyList[p]==MD){
  394.                     FC->FlyList[p]=0xFFFF;
  395.                     break;
  396.                 };
  397.             FC->NFly--;
  398.             for(p=0;p<15;p++)
  399.                 if(FC1->FlyList[p]==0xFFFF){
  400.                     FC1->FlyList[p]=MD;
  401.                     break;
  402.                 };
  403.             FC1->NFly++;
  404.         };
  405.     };
  406.     int RDIR;
  407.     Height=0;
  408.     if(abs(RealVx)>32||abs(RealVy)>32){
  409.         short adx=abs(RealVx);
  410.         short ady=abs(RealVy);
  411.         Height=(adx+ady)>>3;
  412.         if(adx>ady)RDIR=byte(TAtg[div(ady*256,adx).quot]);else
  413.                    RDIR=64-byte(TAtg[div(adx*256,ady).quot]);
  414.         if(RealVx<0)RDIR=128-RDIR;
  415.         if(RealVy<0)RDIR=256-RDIR;
  416.         byte ddr=(256+RDIR-RealDir)&255;
  417.         if(ddr<128){
  418.             if(ddr<5)RealDir=RDIR;
  419.             else RealDir+=5;
  420.         }else{
  421.             ddr=256-ddr;
  422.             if(ddr<5)RealDir=RDIR;
  423.             else RealDir-=5;
  424.         };
  425.         RealDir&=255;
  426.         Direction=((RealDir+80)&255)>>5;
  427.     };
  428.     x=RealX>>9;
  429.     y=RealY>>9;
  430.     byte csp=CurrentSprite;
  431.     LoadCurAnm(0);
  432.     CurrentSprite=csp;
  433.     TicksPerChange=2;
  434. };
  435. void OneObject::ProcessAttackMotion(){
  436.     int cx=(RealX-256)>>11;
  437.     int cy=(RealY-256)>>11;
  438.     int mx=msx>>2;
  439.     int my=msy>>2;
  440.     if(cx<0){
  441.         RealX=256+512;
  442.         cx=0;
  443.     };
  444.     if(cy<0){
  445.         RealY=256+512;
  446.         cy=0;
  447.     };
  448.     if(cx>=mx){
  449.         RealX=(msx<<9)-256;
  450.         cx=mx;
  451.     };
  452.     if(cy>=my){
  453.         RealY=(msy<<9)-256;
  454.         cy=my;
  455.     };
  456.     int Fx=0;
  457.     int Fy=0;
  458.     int dfx;
  459.     int dfy;
  460.     MyHeight=Height;
  461.     FlyCell* FC=&FlyMap[cy][cx];
  462.     FC->GetForces(RealX,RealY,&dfx,&dfy,Index);
  463.     Fx+=dfx;
  464.     Fy+=dfy;
  465.     if(cx>0){
  466.         FC[-1].GetForces(RealX,RealY,&dfx,&dfy,Index);
  467.         Fx+=dfx;
  468.         Fy+=dfy;
  469.     };
  470.     if(cy>0){
  471.         FC[-64].GetForces(RealX,RealY,&dfx,&dfy,Index);
  472.         Fx+=dfx;
  473.         Fy+=dfy;
  474.     };
  475.     if(cx<=mx){
  476.         FC[1].GetForces(RealX,RealY,&dfx,&dfy,Index);
  477.         Fx+=dfx;
  478.         Fy+=dfy;
  479.     };
  480.     if(cy<=my){
  481.         FC[64].GetForces(RealX,RealY,&dfx,&dfy,Index);
  482.         Fx+=dfx;
  483.         Fy+=dfy;
  484.     };
  485.     int rdx=DestX-RealX;
  486.     int rdy=DestY-RealY;
  487.     int ard=abs(rdx)+abs(rdy);
  488.     bool DIRFORWARD=true;
  489.     if(ard<BestDist){
  490.         DIRFORWARD=false;
  491.         if(ard>256){
  492.             rdx=div(rdx<<8,ard).quot;
  493.             rdy=div(rdy<<8,ard).quot;
  494.         };
  495.         Fx-=rdx>>4;
  496.         Fy-=rdy>>4;
  497.     }else{
  498.         if(ard>BestDist+1024){
  499.             if(ard>256){
  500.                 rdx=div(rdx<<8,ard).quot;
  501.                 rdy=div(rdy<<8,ard).quot;
  502.             };
  503.             Fx+=rdx>>3;
  504.             Fy+=rdy>>3;
  505.         }else{
  506.             RealVx-=RealVx>>3;
  507.             RealVy-=RealVy>>3;
  508.         };
  509.     };
  510.     /*int af=abs(Fx)+abs(Fy);
  511.     if(af>32){
  512.         Fx=div(Fx<<5,af).quot;
  513.         Fy=div(Fy<<5,af).quot;
  514.     };*/
  515.     int ax=-(RealVx>>3)+Fx;
  516.     int ay=-(RealVy>>3)+Fy;
  517.     ard=abs(ax)+abs(ay);
  518.     if(ard>32){
  519.         ax=div(ax<<5,ard).quot;
  520.         ay=div(ay<<5,ard).quot;
  521.     };
  522.     RealVx+=ax;
  523.     RealVy+=ay;
  524.     if((!(ax||ay))&&(abs(RealVx)<8&&abs(RealVy<8))){
  525.         RealVx=0;
  526.         RealVy=0;
  527.     };
  528.     /*ard=sqrt((RealVx*RealVx)+(RealVy*RealVy));
  529.     if(ard>MaxSpeed){
  530.         RealVx=div(RealVx*MaxSpeed,ard).quot;
  531.         RealVy=div(RealVy*MaxSpeed,ard).quot;
  532.     };*/
  533.     int rxx=RealX;
  534.     int ryy=RealY;
  535.     RealX+=RealVx;
  536.     RealY+=RealVy;
  537.     int ocx=cx;
  538.     int ocy=cy;
  539.     cx=(RealX-256)>>11;
  540.     cy=(RealY-256)>>11;
  541.     if(cx<0){
  542.         RealX=256+512;
  543.         cx=0;
  544.     };
  545.     if(cy<0){
  546.         RealY=256+512;
  547.         cy=0;
  548.     };
  549.     if(cx>=mx){
  550.         RealX=(msx<<9)-256;
  551.         cx=mx;
  552.     };
  553.     if(cy>=my){
  554.         RealY=(msy<<9)-256;
  555.         cy=my;
  556.     };
  557.     if(ocx!=cx||ocy!=cy){
  558.         FlyCell* FC1=&FlyMap[cy][cx];
  559.         if(FC1->NFly>=15){
  560.             RealX=rxx;
  561.             RealY=ryy;
  562.         }else{
  563.             word MD=Index;
  564.             for(int p=0;p<15;p++)
  565.                 if(FC->FlyList[p]==MD){
  566.                     FC->FlyList[p]=0xFFFF;
  567.                     break;
  568.                 };
  569.             FC->NFly--;
  570.             for(p=0;p<15;p++)
  571.                 if(FC1->FlyList[p]==0xFFFF){
  572.                     FC1->FlyList[p]=MD;
  573.                     break;
  574.                 };
  575.             FC1->NFly++;
  576.         };
  577.     };
  578.     int RDIR;
  579.     Height=0;
  580.     int Dx=-RealX+DestX;
  581.     int Dy=-RealY+DestY;
  582.     Height=(abs(RealVx)+abs(RealVy))>>3;
  583.     if(abs(Dx)>32||abs(Dy)>32){
  584.         int adx=abs(Dx);
  585.         int ady=abs(Dy);
  586.         if(adx>ady)RDIR=byte(TAtg[div(ady*256,adx).quot]);else
  587.                    RDIR=64-byte(TAtg[div(adx*256,ady).quot]);
  588.         if(Dx<0)RDIR=128-RDIR;
  589.         if(Dy<0)RDIR=256-RDIR;
  590.         byte ddr=(256+RDIR-RealDir)&255;
  591.         if(ddr<128){
  592.             if(ddr<16)RealDir=RDIR;
  593.             else RealDir+=16;
  594.         }else{
  595.             ddr=256-ddr;
  596.             if(ddr<16)RealDir=RDIR;
  597.             else RealDir-=16;
  598.         };
  599.         RealDir&=255;
  600.         Direction=((RealDir+80)&255)>>5;
  601.     };
  602.     x=RealX>>9;
  603.     y=RealY>>9;
  604.     byte csp=CurrentSprite;
  605.     //LoadCurAnm(0);
  606.     CurrentSprite=csp;
  607.     TicksPerChange=2;
  608. };
  609. inline void Spota(int x,int y){
  610.     if(x>0&&y>0&&x<msx&&y<msy){
  611.         __asm{
  612.             xor        eax,eax
  613.             mov        al,byte ptr x
  614.             mov        ah, byte ptr y
  615.             shl        eax,1
  616.             mov        word ptr[fmap+eax],16383;
  617.         };
  618.     };
  619. };
  620. extern int tmtmt;
  621. void OneObject::ProcessFly(){
  622.     if(Media!=2)return;
  623.     if(NNUM==MyNation){
  624.         int x0,y0,dx,dx1;
  625.         switch(SpotType){
  626.         case 0:
  627.             if(Lx>1){
  628.             for(byte ux=0;ux<Lx;ux++)
  629.                 for(byte uy=0;uy<Ly;uy++)
  630.                     Spota(x+ux,y+uy);
  631.             }else Spota(x,y);
  632.             break;
  633.         case 1:
  634.             x0=x+(Lx>>1);
  635.             y0=y+(Ly>>1);
  636.             dx=SpotSize;
  637.             Spota(x0,y0);
  638.             Spota(x0+dx,y0);
  639.             Spota(x0-dx,y0);
  640.             Spota(x0,y0+dx);
  641.             Spota(x0,y0-dx);
  642.             break;
  643.         case 2:
  644.             x0=x+(Lx>>1);
  645.             y0=y+(Ly>>1);
  646.             dx=SpotSize;
  647.             dx1=dx-(dx>>2);
  648.             Spota(x0,y0);
  649.             Spota(x0+dx,y0);
  650.             Spota(x0-dx,y0);
  651.             Spota(x0,y0+dx);
  652.             Spota(x0,y0-dx);
  653.             Spota(x0+dx1,y0+dx1);
  654.             Spota(x0-dx1,y0-dx1);
  655.             Spota(x0+dx1,y0-dx1);
  656.             Spota(x0-dx1,y0+dx);
  657.             break;
  658.         };
  659.     };
  660.     if(MagSrcID!=0xFFFF){
  661.         OneObject* OB=Group[MagSrcID];
  662.         if(OB->Magic){
  663.             if(!(tmtmt&31))OB->Magic--;
  664.             if(OB->Magic<8){
  665.                 MakeMeSit();
  666.                 return;
  667.             };
  668.         }else{
  669.             MakeMeSit();
  670.             return;
  671.         };
  672.     };
  673.     byte tc=Ticks;
  674.     if(FlyAttackMode)ProcessAttackMotion();
  675.     else ProcessMotion();
  676.     Ticks=tc;
  677.     Ticks++;
  678.     if(Sdoxlo)TicksPerChange=1;
  679.     if(Ticks<TicksPerChange){
  680.         Ticks++;
  681.         if(TicksPerChange!=255)return;
  682.     };
  683.     Ticks=0;
  684.     int Nsp=CurAnm->count-1;
  685.     if(CurrentSprite<Nsp&&TicksPerChange!=255){
  686.         CurrentSprite++;
  687.         //Ticks=0;
  688.         //TicksPerChange=1;
  689.         return;
  690.     };
  691.     CurrentSprite=0;
  692.     if(Sdoxlo){
  693.         Group[Index]=NULL;
  694.         return;
  695.     };
  696.     if(!NoSearchVictim)SearchVictim();
  697. /*    Addx=0;
  698.     Addy=0;
  699.     Removed=false;
  700.     StandTime++;*/
  701.     if(Life<=0){
  702.         Die();
  703.         return;
  704.     };
  705.     LoadCurAnm(0);
  706.     //if(!Important)
  707.     //if(!NoSearchVictim)SearchVictim();
  708.     Order1* LO=LocalOrder;
  709.     if(!LO)PrioryLevel=0;
  710.     //if(TicksPerChange!=255)LoadCurAnm(0);
  711.     //Important=false;
  712.     if(int(LocalOrder))
  713.     LocalOrder->DoLink(this);
  714.     else{
  715.         DestX=RealX;
  716.         DestY=RealY;
  717.     };
  718. };
  719. void DrawMarker(OneObject* OB);
  720. void DrawMiniMarker(OneObject* OB);
  721. void ShowFlyHealth(OneObject* OB){
  722.     if(MiniMode)DrawMiniMarker(OB);
  723.     else DrawMarker(OB);
  724.     return;
  725.     int    scx=smapx+(OB->RealX>>4-32)-(mapx<<5)-32+20;
  726.     int    scy=smapy+(OB->RealY>>4-32)-(mapy<<5)-16-64-16-OB->Height;
  727.     int dy=64;
  728.     int dx=24;
  729.     Xbar(scx+2,scy+dy-4,dx-4,4,14);
  730.     Xbar(scx-1,scy+dy-3,3,2,clrGreen);
  731.     Xbar(scx+2-4+dx,scy+dy-3,3,2,clrGreen);
  732.     int h=div(OB->Life*(dx-4),OB->MaxLife).quot;
  733.     Hline(scx+3,scy+1-4+dy,scx+1+h,255);
  734.     Hline(scx+3,scy+2-4+dy,scx+1+h,255);
  735. };
  736. /*void ShowFlyingMonsters(){
  737.     word MonsL[1024];
  738.     word MHeight[1024];
  739.     word NMonst;
  740.     int mx=msx>>2-1;
  741.     int my=msy>>2-1;
  742.     int x0=(mapx>>2)-1;
  743.     if(x0<0)x0=0;
  744.     int y0=(mapy>>2)-1;
  745.     if(y0<0)y0=0;
  746.     int x1=mapx+smaplx;
  747.     int y1=mapy+smaply;
  748.     if(x1&3)x1=(x1>>2)+2;
  749.     else x1=(x1>>2)+1;
  750.     if(y1&3)y1=(y1>>2)+2;
  751.     else y1=(y1>>2)+1;
  752.     if(x1>mx)x1=mx;
  753.     if(y1>my)y1=my;
  754.     int mxm=(smaplx<<5)+64;
  755.     int mym=(smaply<<5)+64;
  756.     for(int i=y0;i<=y1;i++)
  757.         for(int j=x0;j<=x1;j++){
  758.             FlyCell* FC=&FlyMap[i][j];
  759.             if(FC->NFly){
  760.                 for(int p=0;p<15;p++){
  761.                     word MID=FC->FlyList[p];
  762.                     if(MID!=0xFFFF){
  763.                         OneObject* OB=Group[MID];
  764.                         if(OB&&OB->Media==2){
  765.                             int xs=(OB->RealX>>4)-(mapx<<5)-16;
  766.                             int ys=(OB->RealY>>4)-(mapy<<5)-16;
  767.                             if(xs>-64&&ys>-64&&xs<mxm&&ys<mym){
  768.                                 Octant* Oc2=OB->CurAnm;
  769.                                 OneSlide* Oc1=&(Oc2->Movie[OB->CurrentSprite]);
  770.                                 byte clr=OB->NNUM&3;
  771.                                 int spr=Oc1->spr;
  772.                                 if(OB->Selected)ShowFlyHealth(OB);
  773.                                 int ady=OB->Height;
  774.                                 if(spr<4096)
  775.                                     if(OB->Invert){
  776.                                         switch(Quality){
  777.                                         case 2:
  778.                                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  779.                                             &MImage[Oc1->FileID],spr+4096);
  780.                                             break;
  781.                                         case 0:
  782.                                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4-4,ys+smapy+Oc1->dy+32-4+ady,
  783.                                                 &MImage[Oc1->FileID],spr+4096);
  784.                                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4-4,ys+smapy+Oc1->dy+32+ady,
  785.                                                 &MImage[Oc1->FileID],spr+4096);
  786.                                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  787.                                                 &MImage[Oc1->FileID],spr+4096);
  788.                                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  789.                                                 &MImage[Oc1->FileID],spr+4096);
  790.                                             break;
  791.                                         case 1:
  792.                                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  793.                                                 &MImage[Oc1->FileID],spr+4096);
  794.                                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  795.                                                 &MImage[Oc1->FileID],spr+4096);
  796.                                             break;
  797.                                         };
  798.                                         ShowRLCItem(xs+32+smapx-Oc1->dx,ys+smapy+Oc1->dy-ady,
  799.                                         &MImage[Oc1->FileID],spr+4096,clr);
  800.                                     }else{
  801.                                         switch(Quality){
  802.                                             case 2:
  803.                                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  804.                                                     &MImage[Oc1->FileID],spr);
  805.                                                 break;
  806.                                             case 0:
  807.                                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4-4,ys+smapy+Oc1->dy+32-4+ady,
  808.                                                     &MImage[Oc1->FileID],spr);
  809.                                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4-4,ys+smapy+Oc1->dy+32+ady,
  810.                                                     &MImage[Oc1->FileID],spr);
  811.                                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  812.                                                     &MImage[Oc1->FileID],spr);
  813.                                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  814.                                                     &MImage[Oc1->FileID],spr);
  815.                                                 break;
  816.                                             case 1:
  817.                                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  818.                                                     &MImage[Oc1->FileID],spr);
  819.                                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  820.                                                     &MImage[Oc1->FileID],spr);
  821.                                                 break;
  822.                                         };
  823.                                         ShowRLCItem(xs+smapx+Oc1->dx,ys+smapy+Oc1->dy-ady,
  824.                                         &MImage[Oc1->FileID],spr,clr);
  825.                                     };
  826.                             };
  827.                         };
  828.                     };
  829.                 };
  830.             };
  831.         };
  832. };*/
  833. void ShowFlyingMonsters(){
  834.     word MonsL[1024];
  835.     word MHeight[1024];
  836.     word NMonst=0;
  837.     int mx=msx>>2-1;
  838.     int my=msy>>2-1;
  839.     int x0=(mapx>>2)-1;
  840.     if(x0<0)x0=0;
  841.     int y0=(mapy>>2)-1;
  842.     if(y0<0)y0=0;
  843.     int x1=mapx+smaplx;
  844.     int y1=mapy+smaply;
  845.     if(x1&3)x1=(x1>>2)+2;
  846.     else x1=(x1>>2)+1;
  847.     if(y1&3)y1=(y1>>2)+2;
  848.     else y1=(y1>>2)+1;
  849.     if(x1>mx)x1=mx;
  850.     if(y1>my)y1=my;
  851.     int mxm=(smaplx<<5)+64;
  852.     int mym=(smaply<<5)+64;
  853.     for(int i=y0;i<=y1;i++)
  854.         for(int j=x0;j<=x1;j++){
  855.             FlyCell* FC=&FlyMap[i][j];
  856.             if(FC->NFly){
  857.                 for(int p=0;p<15;p++){
  858.                     word MID=FC->FlyList[p];
  859.                     if(MID!=0xFFFF){
  860.                         OneObject* OB=Group[MID];
  861.                         if(OB&&OB->Media==2&&NMonst<1024){
  862.                             MonsL[NMonst]=MID;
  863.                             MHeight[NMonst]=OB->Height;
  864.                             NMonst++;
  865.                         };
  866.                     };
  867.                 };
  868.             };
  869.         };
  870.     for(i=0;i<NMonst;i++){
  871.         word MinH=0xFFFF;
  872.         word MD=0xFFFF;
  873.         word JJ=0;
  874.         for(int j=0;j<NMonst;j++){
  875.             word H=MHeight[j];
  876.             if(H<MinH){
  877.                 MinH=H;
  878.                 MD=MonsL[j];
  879.                 JJ=j;
  880.             };
  881.         };
  882.         if(MD!=0xFFFF){
  883.             MHeight[JJ]=0xFFFF;
  884.             OneObject* OB=Group[MD];
  885.             MyHeight=OB->Height;
  886.             int xs=(OB->RealX>>4)-(mapx<<5)-16;
  887.             int ys=(OB->RealY>>4)-(mapy<<5)-16;
  888.             if(xs>-64&&ys>-64&&xs<mxm&&ys<mym){
  889.             Octant* Oc2=OB->CurAnm;
  890.             OneSlide* Oc1=&(Oc2->Movie[OB->CurrentSprite]);
  891.             byte clr=OB->NNUM;
  892.             int spr=Oc1->spr;
  893.             if(OB->Selected)ShowFlyHealth(OB);
  894.             int ady=OB->Height;
  895.             if(spr<4096)
  896.                 if(OB->Invert){
  897.                     switch(Quality){
  898.                         case 2:
  899.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  900.                                 &MImage[Oc1->FileID],spr+4096);
  901.                             break;
  902.                         case 0:
  903.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4-4,ys+smapy+Oc1->dy+32-4+ady,
  904.                                 &MImage[Oc1->FileID],spr+4096);
  905.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4-4,ys+smapy+Oc1->dy+32+ady,
  906.                                 &MImage[Oc1->FileID],spr+4096);
  907.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  908.                                 &MImage[Oc1->FileID],spr+4096);
  909.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  910.                                 &MImage[Oc1->FileID],spr+4096);
  911.                             break;
  912.                         case 1:
  913.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  914.                                 &MImage[Oc1->FileID],spr+4096);
  915.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  916.                                 &MImage[Oc1->FileID],spr+4096);
  917.                             break;
  918.                         };
  919.                             ShowRLCItem(xs+32+smapx-Oc1->dx,ys+smapy+Oc1->dy-ady,
  920.                                 &MImage[Oc1->FileID],spr+4096,clr);
  921.                     }else{
  922.                         switch(Quality){
  923.                             case 2:
  924.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  925.                                     &MImage[Oc1->FileID],spr);
  926.                                 break;
  927.                             case 0:
  928.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4-4,ys+smapy+Oc1->dy+32-4+ady,
  929.                                     &MImage[Oc1->FileID],spr);
  930.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4-4,ys+smapy+Oc1->dy+32+ady,
  931.                                     &MImage[Oc1->FileID],spr);
  932.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  933.                                     &MImage[Oc1->FileID],spr);
  934.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  935.                                     &MImage[Oc1->FileID],spr);
  936.                                 break;
  937.                             case 1:
  938.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  939.                                     &MImage[Oc1->FileID],spr);
  940.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  941.                                     &MImage[Oc1->FileID],spr);
  942.                                 break;
  943.                             };
  944.                             ShowRLCItem(xs+smapx+Oc1->dx,ys+smapy+Oc1->dy-ady,
  945.                                 &MImage[Oc1->FileID],spr,clr);
  946.                     };
  947.                 };
  948.         };
  949.     };
  950. };
  951. void miniShowFlyingMonsters(){
  952.     word MonsL[1024];
  953.     word MHeight[1024];
  954.     word NMonst=0;
  955.     int mx=msx>>2-1;
  956.     int my=msy>>2-1;
  957.     int x0=(mapx>>2)-1;
  958.     if(x0<0)x0=0;
  959.     int y0=(mapy>>2)-1;
  960.     if(y0<0)y0=0;
  961.     int x1=mapx+smaplx;
  962.     int y1=mapy+smaply;
  963.     if(x1&3)x1=(x1>>2)+2;
  964.     else x1=(x1>>2)+1;
  965.     if(y1&3)y1=(y1>>2)+2;
  966.     else y1=(y1>>2)+1;
  967.     if(x1>mx)x1=mx;
  968.     if(y1>my)y1=my;
  969.     int mxm=(smaplx<<5)+64;
  970.     int mym=(smaply<<5)+64;
  971.     for(int i=y0;i<=y1;i++)
  972.         for(int j=x0;j<=x1;j++){
  973.             FlyCell* FC=&FlyMap[i][j];
  974.             if(FC->NFly){
  975.                 for(int p=0;p<15;p++){
  976.                     word MID=FC->FlyList[p];
  977.                     if(MID!=0xFFFF){
  978.                         OneObject* OB=Group[MID];
  979.                         if(OB&&OB->Media==2&&NMonst<1024){
  980.                             MonsL[NMonst]=MID;
  981.                             MHeight[NMonst]=OB->Height;
  982.                             NMonst++;
  983.                         };
  984.                     };
  985.                 };
  986.             };
  987.         };
  988.     for(i=0;i<NMonst;i++){
  989.         word MinH=0xFFFF;
  990.         word MD=0xFFFF;
  991.         word JJ=0;
  992.         for(int j=0;j<NMonst;j++){
  993.             word H=MHeight[j];
  994.             if(H<MinH){
  995.                 MinH=H;
  996.                 MD=MonsL[j];
  997.                 JJ=j;
  998.             };
  999.         };
  1000.         if(MD!=0xFFFF){
  1001.             MHeight[JJ]=0xFFFF;
  1002.             OneObject* OB=Group[MD];
  1003.             MyHeight=OB->Height;
  1004.             int xs=(OB->RealX>>5)-(mapx<<4)-8;
  1005.             int ys=(OB->RealY>>5)-(mapy<<4)-8;
  1006.             if(xs>-64&&ys>-64&&xs<mxm&&ys<mym){
  1007.             Octant* Oc2=OB->CurAnm;
  1008.             OneSlide* Oc1=&(Oc2->Movie[OB->CurrentSprite]);
  1009.             byte clr=OB->NNUM;
  1010.             int spr=Oc1->spr;
  1011.             if(OB->Selected)ShowFlyHealth(OB);
  1012.             int ady=OB->Height>>1;
  1013.             if(spr<4096)
  1014.                 if(OB->Invert){
  1015.                     switch(Quality){
  1016.                         case 2:
  1017.                             ShowRLCItemShadow(xs+16+smapx-(Oc1->dx>>1)-2,ys+smapy+(Oc1->dy>>1)+16+ady,
  1018.                                 &miniMImage[Oc1->FileID],spr+4096);
  1019.                             break;
  1020.                             /*
  1021.                         case 0:
  1022.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4-4,ys+smapy+Oc1->dy+32-4+ady,
  1023.                                 &MImage[Oc1->FileID],spr+4096);
  1024.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4-4,ys+smapy+Oc1->dy+32+ady,
  1025.                                 &MImage[Oc1->FileID],spr+4096);
  1026.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  1027.                                 &MImage[Oc1->FileID],spr+4096);
  1028.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  1029.                                 &MImage[Oc1->FileID],spr+4096);
  1030.                             break;
  1031.                         case 1:
  1032.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  1033.                                 &MImage[Oc1->FileID],spr+4096);
  1034.                             ShowRLCItemShadow(xs+32+smapx-Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  1035.                                 &MImage[Oc1->FileID],spr+4096);
  1036.                             break;*/
  1037.                         };
  1038.  
  1039.                         ShowRLCItem(xs+16+smapx-(Oc1->dx>>1),ys+smapy+(Oc1->dy>>1)-ady,
  1040.                             &miniMImage[Oc1->FileID],spr+4096,clr);
  1041.                     }else{
  1042.                         switch(Quality){
  1043.                             case 2:
  1044.                                 ShowRLCItemShadow(xs+smapx+(Oc1->dx>>1)-2,ys+smapy+(Oc1->dy>>1)+16+ady,
  1045.                                     &miniMImage[Oc1->FileID],spr);
  1046.                                 break;
  1047.                                 /*
  1048.                             case 0:
  1049.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4-4,ys+smapy+Oc1->dy+32-4+ady,
  1050.                                     &MImage[Oc1->FileID],spr);
  1051.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4-4,ys+smapy+Oc1->dy+32+ady,
  1052.                                     &MImage[Oc1->FileID],spr);
  1053.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  1054.                                     &MImage[Oc1->FileID],spr);
  1055.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  1056.                                     &MImage[Oc1->FileID],spr);
  1057.                                 break;
  1058.                             case 1:
  1059.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32-4+ady,
  1060.                                     &MImage[Oc1->FileID],spr);
  1061.                                 ShowRLCItemShadow(xs+smapx+Oc1->dx-4,ys+smapy+Oc1->dy+32+ady,
  1062.                                     &MImage[Oc1->FileID],spr);
  1063.                                 break;*/
  1064.                             };
  1065.                         ShowRLCItem(xs+smapx+(Oc1->dx>>1),ys+smapy+(Oc1->dy>>1)-ady,
  1066.                             &miniMImage[Oc1->FileID],spr,clr);
  1067.                     };
  1068.                 };
  1069.         };
  1070.     };
  1071. };
  1072. inline bool PInside(int x,int y,int x1,int y1,int xp,int yp){
  1073.     if(xp>=x&&xp<=x1&&yp>=y&&yp<=y1)return true;
  1074.     else return false;
  1075. };
  1076. word SelectFly(byte NI,int xr,int yr,int xr1,int yr1,word *Collect,word* Ser,bool WRITE){
  1077.     int x,y,x1p,y1p,x1,y1;
  1078.     int xp=xr>>5;
  1079.     int yp=yr>>5;
  1080.     int xp1=xr1>>5;
  1081.     int yp1=yr1>>5;
  1082.     if(xp>xp1){
  1083.         x=xp1;
  1084.         x1=xp;
  1085.     }else{
  1086.         x1=xp1;
  1087.         x=xp;
  1088.     };
  1089.     if(yp>yp1){
  1090.         y=yp1;
  1091.         y1=yp;
  1092.     }else{
  1093.         y1=yp1;
  1094.         y=yp;
  1095.     };
  1096.     x1p=x1;
  1097.     y1p=y1;
  1098.     int mx=msx>>2-1;
  1099.     int my=msy>>2-1;
  1100.     int x0=(x>>2)-1;
  1101.     if(x0<0)x0=0;
  1102.     int y0=(y>>2)-1;
  1103.     if(y0<0)y0=0;
  1104.     if(x1&3)x1=(x1>>2)+2;
  1105.     else x1=(x1>>2)+1;
  1106.     if(y1&3)y1=(y1>>2)+2;
  1107.     else y1=(y1>>2)+1;
  1108.     if(x1>mx)x1=mx;
  1109.     if(y1>my)y1=my;
  1110.     int mxm=(smaplx<<5)+64;
  1111.     int mym=(smaply<<5)+64;
  1112.     int NSLC=0;
  1113.     x=xr;
  1114.     y=yr;
  1115.     x1p=xr1;
  1116.     y1p=yr1;
  1117.     for(int i=y0;i<=y1;i++)
  1118.         for(int j=x0;j<=x1;j++){
  1119.             FlyCell* FC=&FlyMap[i][j];
  1120.             if(FC->NFly){
  1121.                 for(int p=0;p<15;p++){
  1122.                     word MID=FC->FlyList[p];
  1123.                     if(MID!=0xFFFF){
  1124.                         OneObject* OB=Group[MID];
  1125.                         if(OB&&OB->Media==2&&OB->NNUM==NI&&!OB->Selected){
  1126.                             int xs=(OB->RealX>>4)-40;
  1127.                             int ys=(OB->RealY>>4)-40+10;
  1128.                             int xs1=xs+80;
  1129.                             int ys1=ys+80;
  1130.                             if(PInside(x,y,x1p,y1p,xs,ys)||
  1131.                                PInside(x,y,x1p,y1p,xs1,ys)||
  1132.                                PInside(x,y,x1p,y1p,xs,ys1)||
  1133.                                PInside(x,y,x1p,y1p,xs1,ys1)||
  1134.                                PInside(xs,ys,xs1,ys1,x,y)||
  1135.                                PInside(xs,ys,xs1,ys1,x1p,y)||
  1136.                                PInside(xs,ys,xs1,ys1,x,y1p)||
  1137.                                PInside(xs,ys,xs1,ys1,x1p,y1p)){
  1138.                                 if(WRITE){
  1139.                                     Collect[NSLC]=MID;
  1140.                                     Ser[NSLC]=OB->Serial;
  1141.                                     OB->Selected=true;
  1142.                                 };
  1143.                                 NSLC++;
  1144.                             };
  1145.                         };
  1146.                     };
  1147.                 };
  1148.             };
  1149.         };
  1150.     return NSLC;
  1151. };
  1152. word GoodSelectFly(byte NI,int xr,int yr,int xr1,int yr1,word *Collect,word* Ser,bool WRITE,CHOBJ* FN,int NN){
  1153.     int x,y,x1p,y1p,x1,y1;
  1154.     int xp=xr>>5;
  1155.     int yp=yr>>5;
  1156.     int xp1=xr1>>5;
  1157.     int yp1=yr1>>5;
  1158.     if(xp>xp1){
  1159.         x=xp1;
  1160.         x1=xp;
  1161.     }else{
  1162.         x1=xp1;
  1163.         x=xp;
  1164.     };
  1165.     if(yp>yp1){
  1166.         y=yp1;
  1167.         y1=yp;
  1168.     }else{
  1169.         y1=yp1;
  1170.         y=yp;
  1171.     };
  1172.     x1p=x1;
  1173.     y1p=y1;
  1174.     int mx=msx>>2-1;
  1175.     int my=msy>>2-1;
  1176.     int x0=(x>>2)-1;
  1177.     if(x0<0)x0=0;
  1178.     int y0=(y>>2)-1;
  1179.     if(y0<0)y0=0;
  1180.     if(x1&3)x1=(x1>>2)+2;
  1181.     else x1=(x1>>2)+1;
  1182.     if(y1&3)y1=(y1>>2)+2;
  1183.     else y1=(y1>>2)+1;
  1184.     if(x1>mx)x1=mx;
  1185.     if(y1>my)y1=my;
  1186.     int mxm=(smaplx<<5)+64;
  1187.     int mym=(smaply<<5)+64;
  1188.     int NSLC=0;
  1189.     x=xr;
  1190.     y=yr;
  1191.     x1p=xr1;
  1192.     y1p=yr1;
  1193.     for(int i=y0;i<=y1;i++)
  1194.         for(int j=x0;j<=x1;j++){
  1195.             FlyCell* FC=&FlyMap[i][j];
  1196.             if(FC->NFly){
  1197.                 for(int p=0;p<15;p++){
  1198.                     word MID=FC->FlyList[p];
  1199.                     if(MID!=0xFFFF){
  1200.                         OneObject* OB=Group[MID];
  1201.                         if(OB&&(!OB->Selected)&&OB->Media==2&&OB->NNUM==NI&&((!FN)||FN(OB,NN))){
  1202.                             int xs=(OB->RealX>>4)-40;
  1203.                             int ys=(OB->RealY>>4)-40+10;
  1204.                             int xs1=xs+80;
  1205.                             int ys1=ys+80;
  1206.                             if(PInside(x,y,x1p,y1p,xs,ys)||
  1207.                                PInside(x,y,x1p,y1p,xs1,ys)||
  1208.                                PInside(x,y,x1p,y1p,xs,ys1)||
  1209.                                PInside(x,y,x1p,y1p,xs1,ys1)||
  1210.                                PInside(xs,ys,xs1,ys1,x,y)||
  1211.                                PInside(xs,ys,xs1,ys1,x1p,y)||
  1212.                                PInside(xs,ys,xs1,ys1,x,y1p)||
  1213.                                PInside(xs,ys,xs1,ys1,x1p,y1p)){
  1214.                                 if(WRITE){
  1215.                                     Collect[NSLC]=MID;
  1216.                                     Ser[NSLC]=OB->Serial;
  1217.                                     OB->Selected=true;
  1218.                                 };
  1219.                                 NSLC++;
  1220.                             };
  1221.                         };
  1222.                     };
  1223.                 };
  1224.             };
  1225.         };
  1226.     return NSLC;
  1227. };
  1228. void FlySendToLink(OneObject* OB);
  1229. void OneObject::SendFlyTo(int x,int y,byte Prio){
  1230.     if(PrioryLevel>Prio)return;
  1231.     if(!cpbMoving)return;
  1232.     Order1* Or1=GetOrdBlock();
  1233.     if(!int(Or1))return;
  1234.     Or1->PrioryLevel=Prio&127;
  1235.     Or1->NextOrder=NULL;
  1236.     Or1->OrderType=2;
  1237.     Or1->OrderTime=0;
  1238.     Or1->DoLink=&FlySendToLink;
  1239.     Or1->info.MoveToXY.x=x;
  1240.     Or1->info.MoveToXY.y=y;
  1241.     Order1* LOR=LocalOrder;
  1242.     if(int(LOR)){
  1243.         ClearOrders();
  1244.         if(LOR->OrderType!=2)StandTime=0; 
  1245.     }else StandTime=0;
  1246.     if(int(InLineCom)){
  1247.         FreeAsmLink();
  1248.     };
  1249.     LocalOrder=Or1;
  1250.     //OrderReport=NULL;
  1251.     //MessageKind=0;
  1252.     //Sender=0xFFFF;
  1253.     DestX=(int(x)<<9)+256;
  1254.     DestY=(int(y)<<9)+256;
  1255.     PrioryLevel=Prio&127;
  1256. };
  1257. void FlySendToLink(OneObject* OB){
  1258.     OB->FlyAttackMode=false;
  1259.     int dst=abs(OB->RealX-OB->DestX)+abs(OB->RealY-OB->DestY);
  1260.     if(dst<2048){
  1261.         if(int(OB->LocalOrder)){
  1262.             Order1* Loc1=OB->LocalOrder->NextOrder;
  1263.             OB->FreeOrdBlock(OB->LocalOrder);
  1264.             OB->LocalOrder=Loc1;
  1265.         };
  1266.     };
  1267. };
  1268. void FlyAttackLink(OneObject* OB);
  1269. void OneObject::FlyAttack(word OID,byte Prio){
  1270.     assert(OID!=0xFFFF);
  1271.     if(PrioryLevel>Prio)return;
  1272.     if(!cpbMoving)return;
  1273.     OneObject* OBB=Group[OID];
  1274.     if(!OBB)return;
  1275.     if(OBB->Sdoxlo||OBB->NMask&NMask)return;
  1276.     Order1* Or1=GetOrdBlock();
  1277.     if(!int(Or1))return;
  1278.     Or1->PrioryLevel=Prio&127;
  1279.     Or1->NextOrder=NULL;
  1280.     Or1->OrderType=3;
  1281.     Or1->OrderTime=0;
  1282.     Or1->DoLink=&FlyAttackLink;
  1283.     Or1->info.MoveToObj.ObjIndex=OID;
  1284.     Order1* LOR=LocalOrder;
  1285.     if(int(LOR)){
  1286.         ClearOrders();
  1287.         if(LOR->OrderType!=2)StandTime=0; 
  1288.     }else StandTime=0;
  1289.     if(int(InLineCom)){
  1290.         FreeAsmLink();
  1291.     };
  1292.     LocalOrder=Or1;
  1293.     EnemyID=OID;
  1294.     EnemySN=OBB->Serial;
  1295.     //OrderReport=NULL;
  1296.     //MessageKind=0;
  1297.     //Sender=0xFFFF;
  1298.     DestX=(int(x)<<9)+256;
  1299.     DestY=(int(y)<<9)+256;
  1300.     PrioryLevel=Prio&127;
  1301.     FlyAttackMode=true;
  1302. };
  1303. void FlyAttackLink(OneObject* OBJ){
  1304.     OBJ->LoadCurAnm(0);
  1305.     OBJ->FlyAttackMode=1;
  1306.     word MID=OBJ->LocalOrder->info.MoveToObj.ObjIndex;
  1307.     if(MID!=0xFFFF){
  1308.         OneObject* OB=Group[MID];
  1309.         if(OB&&!((OB->NMask&OBJ->NMask)||OB->Sdoxlo||OB->Serial!=OBJ->EnemySN)){
  1310.             if(OB->Media!=2){
  1311.                 OBJ->DestX=(OB->x<<9)+256;
  1312.                 OBJ->DestY=(OB->y<<9)+256;
  1313.             }else{
  1314.                 OBJ->DestX=OB->RealX;
  1315.                 OBJ->DestY=OB->RealY;
  1316.             };
  1317.         }else{
  1318.             Order1* Loc1=OBJ->LocalOrder->NextOrder;
  1319.             OBJ->FreeOrdBlock(OBJ->LocalOrder);
  1320.             OBJ->LocalOrder=Loc1;
  1321.             OBJ->FlyAttackMode=0;
  1322.             return;
  1323.         };
  1324.         int wcx=OBJ->RealX+((int(OBJ->wepX)+int(OBJ->Ref.General->Wdx[OBJ->Direction]))<<4)-256;
  1325.         int wcy=OBJ->RealY+((int(OBJ->wepY)+int(OBJ->Ref.General->Wdy[OBJ->Direction]))<<4)-(OBJ->Height<<4)-256;
  1326.         int adx=OBJ->DestX-wcx-256;
  1327.         int ady=OBJ->DestY-wcy-256;
  1328.         if(OBJ->delay)OBJ->delay--;
  1329.         if(OBJ->Weap&&abs(adx)+abs(ady)<OBJ->BestDist+2048&&!OBJ->delay){
  1330.             OBJ->delay=OBJ->MaxDelay;
  1331.             OBJ->LoadCurAnm(1);
  1332.             //OBJ->Direction=
  1333.             CreateUniExObj(OBJ->Weap,(wcx>>2),(wcy>>2),64,OBJ->NMask,OBJ,OB->x,OB->y,OB->Index);
  1334.             OBJ->MakeDamage(0,OBJ->Ref.General->LifeShotLost,OB);
  1335.         };
  1336.     }else{
  1337.         if(OBJ->InLineCom)OBJ->FreeAsmLink();
  1338.         Order1* Loc1=OBJ->LocalOrder->NextOrder;
  1339.         OBJ->FreeOrdBlock(OBJ->LocalOrder);
  1340.         OBJ->LocalOrder=Loc1;
  1341.         OBJ->FlyAttackMode=0;            
  1342.         return;
  1343.     };
  1344. };
  1345. void SetFlyMarkers(){
  1346.     for(int i=0;i<MaxObj;i++){
  1347.         OneObject* OB=Group[i];
  1348.         if(OB&&OB->Media==2&&!OB->Sdoxlo)
  1349.         FlyMops[OB->RealY>>9][OB->RealX>>9]=OB->Index;
  1350.     };
  1351. };
  1352. void ClearFlyMarkers(){
  1353.     for(int i=0;i<MaxObj;i++){
  1354.         OneObject* OB=Group[i];
  1355.         if(OB&&OB->Media==2)
  1356.         FlyMops[OB->RealY>>9][OB->RealX>>9]=0xFFFF;
  1357.     };
  1358. };
  1359. void UFOLink(OneObject* OB);
  1360. void OneObject::MakeMeUFO(){
  1361.     if(!cpbMoving)return;
  1362.     ClearOrders();
  1363.     NMask=255;
  1364.     if(int(InLineCom)){
  1365.         FreeAsmLink();
  1366.     };
  1367.     Order1* Or1=GetOrdBlock();
  1368.     if(!int(Or1))return;
  1369.     Or1->NextOrder=NULL;
  1370.     Or1->OrderType=92;
  1371.     Or1->OrderTime=0;
  1372.     Or1->DoLink=&UFOLink;
  1373.     Or1->info.UFO.xd=msx>>1;
  1374.     Or1->info.UFO.yd=msy>>1;
  1375.     Or1->info.UFO.time=0;
  1376.     Or1->info.UFO.BuildID=0xFFFF;
  1377.     Or1->info.UFO.BSN=0xFFFF;
  1378.     Order1* LOR=LocalOrder;
  1379.     LocalOrder=Or1;
  1380.     //OrderReport=NULL;
  1381.     //MessageKind=0;
  1382.     //Sender=0xFFFF;
  1383.     PrioryLevel=255;
  1384. };
  1385. void UFOLink(OneObject* OB){
  1386.     word BuildID=OB->LocalOrder->info.UFO.BuildID;
  1387.     byte Time=OB->LocalOrder->info.UFO.time;
  1388.     if(BuildID==0xFFFF){
  1389.         if(Time){
  1390.             OB->LocalOrder->info.UFO.time--;
  1391.         }else{
  1392.             OB->LocalOrder->info.UFO.time=50;
  1393.             OB->LocalOrder->info.UFO.xd=8+((int(rando())*(msx-16))>>15);
  1394.             OB->LocalOrder->info.UFO.yd=8+((int(rando())*(msy-16))>>15);
  1395.             OB->DestX=(int(OB->LocalOrder->info.UFO.xd)<<9)+256;
  1396.             OB->DestY=(int(OB->LocalOrder->info.UFO.yd)<<9)+256;
  1397.         };
  1398.     }else{
  1399.         word BID=OB->LocalOrder->info.UFO.BuildID;
  1400.         word BSN=OB->LocalOrder->info.UFO.BSN;
  1401.         OneObject* FOB=Group[BID];
  1402.         if(FOB&&FOB->Serial==BSN){
  1403.             int xd=(int(FOB->x)<<9)+256+512;
  1404.             int yd=(int(FOB->y)<<9)+256+512;
  1405.             int dstt=abs(xd-OB->RealX)+abs(yd-OB->RealY);
  1406.             if(dstt<64){
  1407.                 //Transforming
  1408.                 Visuals* GO=(Visuals*)(FOB->Nat->Mon[FOB->Ref.General->IDforUFO]);
  1409.                 OneObject* G=FOB;
  1410.                 CreateStrangeObject(11,OB->NNUM,(OB->RealX>>9)+1,(OB->RealY>>9)+1,OB->Index);
  1411.                 FOB->DefaultSettings(GO);
  1412.                 G->NIndex=FOB->Ref.General->IDforUFO;
  1413.                 G->Teleport=false;
  1414.                 G->capTeleport=GO->Teleport;
  1415.                 G->VisRadius=GO->VisRadius;
  1416.                 G->VisSpots=GO->VisSpots;
  1417.                 G->SpotType=GO->SpotType;
  1418.                 G->SpotSize=GO->SpotSize;
  1419.                 G->DangerZone=GO->DangerZone;
  1420.                 G->NoSearchVictim=GO->NoSearchVictim;
  1421.                 G->NoAnswer=GO->NoAnswer;
  1422.                 G->NeedNoHelp=GO->NeedNoHelp;
  1423.                 G->Ready=true;
  1424.                 G->wepX=GO->wepX;
  1425.                 G->wepY=GO->wepY;
  1426.                 G->MaxDelay=GO->delay;
  1427.                 G->delay=0;
  1428.                 G->NearBase=0xFFFF;
  1429.                 G->capBase=GO->cpbBase;
  1430.                 G->RStage=0;
  1431.                 G->RType=0;
  1432.                 G->RAmount=0;
  1433.                 G->AnmGoKind=1;
  1434.                 G->capBuild=GO->cpbBuild;
  1435.                 G->GroupIndex=NULL;
  1436.                 G->cpbMoving=GO->cpbMoving;
  1437.                 G->AbRes=0;
  1438.                 if(GO->AGold)G->AbRes|=2;
  1439.                 if(GO->AWood)G->AbRes|=4;
  1440.                 if(!GO->SizeX)GO->SizeX=1;
  1441.                 if(!GO->SizeY)GO->SizeY=1;
  1442.                 G->Lx=GO->SizeX;
  1443.                 G->Ly=GO->SizeY;
  1444.                 G->TempFlag=false;
  1445.                 G->Mobilised=false;
  1446.                 G->Wars=NULL;
  1447.                 G->Selected=false;
  1448.                 G->Borg=false;
  1449.                 G->Life=GO->info.Basic.MaxLife;
  1450.                 G->MaxLife=GO->info.Basic.MaxLife;
  1451.                 G->Ref.Visual=GO;
  1452.                 G->Push=false;
  1453.                 memset(&(G->ARegs),0,sizeof G->ARegs);
  1454.                 G->LoadAnimation(0,0,0);
  1455.                 G->LoadCurAnm(0);
  1456.                 G->LocalOrder=NULL;
  1457.                 G->Attack=false;
  1458.                 //G->OrderReport=NULL;
  1459.                 //G->MessageFlags=0;
  1460.                 G->PrioryLevel=0;
  1461.                 //G->MessageKind=0;
  1462.                 G->Ticks=0;
  1463.                 G->TicksPerChange=10;
  1464.                 G->Wait=0;
  1465.                 G->Addx=0;
  1466.                 G->Addy=0;
  1467.                 G->Npush=0;
  1468.                 G->StandTime=100;
  1469.                 G->Sdoxlo=false;
  1470.                 G->Weap=GO->Weap;
  1471.             }else{
  1472.                 OB->DestX=xd;
  1473.                 OB->DestY=yd;
  1474.             };
  1475.         }else{
  1476.             OB->LocalOrder->info.UFO.BuildID=0xFFFF;
  1477.             OB->LocalOrder->info.UFO.BSN=0xFFFF;
  1478.             OB->LocalOrder->info.UFO.time=0;
  1479.         };
  1480.     };
  1481. };
  1482. void ProcessUFO(){
  1483.     //find buildings to produce
  1484.     for(int i=0;i<MAXOBJECT;i++){
  1485.         OneObject* OB=Group[i];
  1486.         if(OB&&OB->UFOTrans&&OB->Ready){
  1487.             //Let us find UFO
  1488.             for(int j=0;j<MaxObject;j++){
  1489.                 OneObject* UOB=Group[j];
  1490.                 if(UOB&&UOB->Ref.General->UFO){
  1491.                     Order1* OR1=UOB->LocalOrder;
  1492.                     if(OR1&&OR1->OrderType==92&&OR1->info.UFO.BuildID==0xFFFF){
  1493.                         OR1->info.UFO.BuildID=i;
  1494.                         OR1->info.UFO.BSN=OB->Serial;
  1495.                         OB->UFOTrans=false;
  1496.                         goto uuu;
  1497.                     };
  1498.                 };
  1499.             };
  1500.         };
  1501. uuu:;
  1502.     };
  1503. };