home *** CD-ROM | disk | FTP | other *** search
/ WarCraft 2000 - Nuclear Epidemic / W2000.nrg / SOURCE.War2000 / Multi.cpp < prev    next >
C/C++ Source or Header  |  1998-11-13  |  35KB  |  1,521 lines

  1. //MULTIPLAYER ORGANIZATION
  2. #include "ddini.h"
  3. #include "ResFile.h"
  4. #include "FastDraw.h"
  5. #include "mgraph.h"
  6. #include "mouse.h"
  7. #include "menu.h"
  8. #include "MapDiscr.h"
  9. #include "math.h"
  10. #include "walls.h"
  11. #include "FlyObj.h"
  12. extern int RESRC[8][8];
  13. extern int tmtmt;
  14. extern word rpos;
  15. word GetOwner(int x,int y);
  16. //Nations presence array
  17. byte NPresence[64][64];
  18. Nation NATIONS[8];
  19. byte MyNation;
  20. word* Selm[8];
  21. word* SerN[8];
  22. word NSL[8];
  23. bool CmdDone[8192];
  24. typedef  bool CHOBJ(OneObject* OB,int N);
  25. void CreateUnit(Nation* NT,byte x,byte y,word ID);
  26. //Execute buffer 
  27. DWORD Signatur[2049];
  28. byte ExBuf[8192];
  29. int EBPos;
  30.  
  31. //
  32. void InitEBuf(){
  33.     EBPos=0;
  34. };
  35.  
  36. //[1][ni][x][y][x1][y1]
  37. void CmdCreateSelection(byte NI,byte x,byte y,byte x1,byte y1){
  38.     ExBuf[EBPos]=1;
  39.     ExBuf[EBPos+1]=NI;
  40.     ExBuf[EBPos+2]=x;
  41.     ExBuf[EBPos+3]=y;
  42.     ExBuf[EBPos+4]=x1;
  43.     ExBuf[EBPos+5]=y1;
  44.     EBPos+=6;
  45. };
  46. //[2][ni][x][y]
  47. void CmdSendToXY(byte NI,byte x,byte y){
  48.     ExBuf[EBPos]=2;
  49.     ExBuf[EBPos+1]=NI;
  50.     ExBuf[EBPos+2]=x;
  51.     ExBuf[EBPos+3]=y;
  52.     EBPos+=4;
  53. };
  54. //[3][ni][w:ObjID]
  55. void CmdAttackObj(byte NI,word ObjID){
  56.     ExBuf[EBPos]=3;
  57.     ExBuf[EBPos+1]=NI;
  58.     *(word*)(&ExBuf[EBPos+2])=ObjID;
  59.     EBPos+=4;
  60. };
  61. //[4][ni][x][y][w:Type]
  62. void CmdCreateTerrain(byte NI,byte x,byte y,word Type){
  63.     ExBuf[EBPos]=4;
  64.     ExBuf[EBPos+1]=NI;
  65.     ExBuf[EBPos+2]=x;
  66.     ExBuf[EBPos+3]=y;
  67.     *(word*)(&ExBuf[EBPos+4])=Type;
  68.     EBPos+=6;
  69. };
  70. //[5][ni][x][y][w:Type]
  71. void CmdCreateBuilding(byte NI,byte x,byte y,word Type){
  72.     ExBuf[EBPos]=5;
  73.     ExBuf[EBPos+1]=NI;
  74.     ExBuf[EBPos+2]=x;
  75.     ExBuf[EBPos+3]=y;
  76.     *(word*)(&ExBuf[EBPos+4])=Type;
  77.     EBPos+=6;
  78. };
  79. //[6][ni][w:ObjID]
  80. void CmdProduceObj(byte NI,word Type){
  81.     ExBuf[EBPos]=6;
  82.     ExBuf[EBPos+1]=NI;
  83.     *(word*)(&ExBuf[EBPos+2])=Type;
  84.     EBPos+=4;
  85. };
  86. //[7][ni][index]
  87. void CmdMemSelection(byte NI,byte Index){
  88.     ExBuf[EBPos]=7;
  89.     ExBuf[EBPos+1]=NI;
  90.     ExBuf[EBPos+2]=Index;
  91.     EBPos+=3;
  92. };
  93. //[8][ni][Index]
  94. void CmdRememSelection(byte NI,byte Index){
  95.     ExBuf[EBPos]=8;
  96.     ExBuf[EBPos+1]=NI;
  97.     ExBuf[EBPos+2]=Index;
  98.     EBPos+=3;
  99. };
  100. //[9][ni][ObjID]
  101. void CmdBuildObj(byte NI,word ObjID){
  102.     ExBuf[EBPos]=9;
  103.     ExBuf[EBPos+1]=NI;
  104.     *(word*)(&ExBuf[EBPos+2])=ObjID;
  105.     EBPos+=4;
  106. };
  107. //[0A][NI][kind][owner][count:16][x1][y1][x2][y2]...
  108. //building wall
  109. void CmdBuildWall(byte NI){
  110.     if(!TMPCluster.ClusterSize)return;
  111.     ExBuf[EBPos]=0xA;
  112.     ExBuf[EBPos+1]=NI;
  113.     TMPCluster.CreateData(NI,&ExBuf[EBPos+2]);
  114.     EBPos+=TMPCluster.GetDataSize()+2;
  115. };
  116. //[0B][NI][LINK INDEX]
  117. void CmdRepairWall(byte NI,word LIN){
  118.     ExBuf[EBPos]=0xB;
  119.     ExBuf[EBPos+1]=NI;
  120.     *(word*)(&ExBuf[EBPos+2])=LIN;
  121.     EBPos+=4;
  122. };
  123. //[0C][NI][LINK INDEX:16]
  124. void CmdDamageWall(byte NI,word LIN){
  125.     ExBuf[EBPos]=0xC;
  126.     ExBuf[EBPos+1]=NI;
  127.     *(word*)(&ExBuf[EBPos+2])=LIN;
  128.     EBPos+=4;
  129. };
  130. //[0D][NI][x][y][ResID]
  131. void CmdTakeRes(byte NI,byte x,byte y,byte ResID){
  132.     ExBuf[EBPos]=0xD;
  133.     ExBuf[EBPos+1]=NI;
  134.     ExBuf[EBPos+2]=x;
  135.     ExBuf[EBPos+3]=y;
  136.     ExBuf[EBPos+4]=ResID;
  137.     EBPos+=5;
  138. };
  139. //[0E][NI][UpgradeIndex:16]
  140. void CmdPerformUpgrade(byte NI,word UI){
  141.     ExBuf[EBPos]=0xE;
  142.     ExBuf[EBPos+1]=NI;
  143.     *(word*)(&ExBuf[EBPos+2])=UI;
  144.     EBPos+=4;
  145. };
  146. //[0F][NI][OID:16]
  147. void CmdGetOil(byte NI,word UI){
  148.     ExBuf[EBPos]=0xF;
  149.     ExBuf[EBPos+1]=NI;
  150.     *(word*)(&ExBuf[EBPos+2])=UI;
  151.     EBPos+=4;
  152. };
  153. //[10][NI][x][y][x1][y1][Kind]
  154. void CmdCreateKindSelection(byte NI,byte x,byte y,byte x1,byte y1,byte Kind){
  155.     ExBuf[EBPos]=16;
  156.     ExBuf[EBPos+1]=NI;
  157.     ExBuf[EBPos+2]=x;
  158.     ExBuf[EBPos+3]=y;
  159.     ExBuf[EBPos+4]=x1;
  160.     ExBuf[EBPos+5]=y1;
  161.     ExBuf[EBPos+6]=Kind;
  162.     EBPos+=7;
  163. };
  164. //[11][NI][x][y][x1][y1][Type]
  165. void CmdCreateTypeSelection(byte NI,byte x,byte y,byte x1,byte y1,word Type){
  166.     ExBuf[EBPos]=17;
  167.     ExBuf[EBPos+1]=NI;
  168.     ExBuf[EBPos+2]=x;
  169.     ExBuf[EBPos+3]=y;
  170.     ExBuf[EBPos+4]=x1;
  171.     ExBuf[EBPos+5]=y1;
  172.     *(word*)(&ExBuf[EBPos+6])=Type;
  173.     EBPos+=8;
  174. };
  175. //[12][ni][x:16][y:16][x1:16][y1:16]
  176. void CmdCreateGoodSelection(byte NI,word x,word y,word x1,word y1){
  177.     bool Addon=false;
  178.     if(GetKeyState(VK_SHIFT)&0x8000)Addon=true;
  179.     ExBuf[EBPos]=18;
  180.     ExBuf[EBPos+1]=NI;
  181.     *(word*)(&ExBuf[EBPos+2])=x;
  182.     *(word*)(&ExBuf[EBPos+4])=y;
  183.     *(word*)(&ExBuf[EBPos+6])=x1;
  184.     *(word*)(&ExBuf[EBPos+8])=y1;
  185.     ExBuf[EBPos+10]=Addon;
  186.     EBPos+=11;
  187. };
  188. //[13][NI][x][y][x1][y1][Kind]
  189. void CmdCreateGoodKindSelection(byte NI,word x,word y,word x1,word y1,byte Kind){
  190.     bool Addon=false;
  191.     if(GetKeyState(VK_SHIFT)&0x8000)Addon=true;
  192.     ExBuf[EBPos]=19;
  193.     ExBuf[EBPos+1]=NI;
  194.     *(word*)(&ExBuf[EBPos+2])=x;
  195.     *(word*)(&ExBuf[EBPos+4])=y;
  196.     *(word*)(&ExBuf[EBPos+6])=x1;
  197.     *(word*)(&ExBuf[EBPos+8])=y1;
  198.     ExBuf[EBPos+10]=Kind;
  199.     ExBuf[EBPos+11]=Addon;
  200.     EBPos+=12;
  201. };
  202. //[14][NI][x][y][x1][y1][Type]
  203. void CmdCreateGoodTypeSelection(byte NI,word x,word y,word x1,word y1,word Type){
  204.     bool Addon=false;
  205.     if(GetKeyState(VK_SHIFT)&0x8000)Addon=true;
  206.     ExBuf[EBPos]=20;
  207.     ExBuf[EBPos+1]=NI;
  208.     *(word*)(&ExBuf[EBPos+2])=x;
  209.     *(word*)(&ExBuf[EBPos+4])=y;
  210.     *(word*)(&ExBuf[EBPos+6])=x1;
  211.     *(word*)(&ExBuf[EBPos+8])=y1;
  212.     *(word*)(&ExBuf[EBPos+10])=Type;
  213.     ExBuf[EBPos+12]=Addon;
  214.     EBPos+=13;
  215. };
  216. //[15][NI][x][y]
  217. void CmdSetDst(byte NI,byte x,byte y){
  218.     ExBuf[EBPos]=21;
  219.     ExBuf[EBPos+1]=NI;
  220.     ExBuf[EBPos+2]=x;
  221.     ExBuf[EBPos+3]=y;
  222.     EBPos+=4;
  223. };
  224. //[16][NI][x][y]
  225. void CmdSendToPoint(byte NI,byte x,byte y){
  226.     ExBuf[EBPos]=22;
  227.     ExBuf[EBPos+1]=NI;
  228.     ExBuf[EBPos+2]=x;
  229.     ExBuf[EBPos+3]=y;
  230.     EBPos+=4;
  231. };
  232. //[17][ni][x][y]
  233. void CmdAttackToXY(byte NI,byte x,byte y){
  234.     ExBuf[EBPos]=23;
  235.     ExBuf[EBPos+1]=NI;
  236.     ExBuf[EBPos+2]=x;
  237.     ExBuf[EBPos+3]=y;
  238.     EBPos+=4;
  239. };
  240. //[18][ni]
  241. void CmdStop(byte NI){
  242.     ExBuf[EBPos]=24;
  243.     ExBuf[EBPos+1]=NI;
  244.     EBPos+=2;
  245. };
  246. //[19][ni]
  247. void CmdStandGround(byte NI){
  248.     ExBuf[EBPos]=25;
  249.     ExBuf[EBPos+1]=NI;
  250.     EBPos+=2;
  251. };
  252. //[1A][ni][x][y]
  253. void CmdPatrol(byte NI,byte x,byte y){
  254.     ExBuf[EBPos]=26;
  255.     ExBuf[EBPos+1]=NI;
  256.     ExBuf[EBPos+2]=x;
  257.     ExBuf[EBPos+3]=y;
  258.     EBPos+=4;
  259. };
  260. //[1B][ni][x][y]
  261. void CmdRepair(byte NI,byte x,byte y){
  262.     ExBuf[EBPos]=27;
  263.     ExBuf[EBPos+1]=NI;
  264.     ExBuf[EBPos+2]=x;
  265.     ExBuf[EBPos+3]=y;
  266.     EBPos+=4;
  267. };
  268. //[1C][ni][x][y]
  269. void CmdGetResource(byte NI,byte x,byte y){
  270.     ExBuf[EBPos]=28;
  271.     ExBuf[EBPos+1]=NI;
  272.     ExBuf[EBPos+2]=x;
  273.     ExBuf[EBPos+3]=y;
  274.     EBPos+=4;
  275. };
  276. //[1D][ni][x][y][kind]
  277. void CmdComplexAttackPoint(byte NI,byte x,byte y,byte kind){
  278.     ExBuf[EBPos]=29;
  279.     ExBuf[EBPos+1]=NI;
  280.     ExBuf[EBPos+2]=x;
  281.     ExBuf[EBPos+3]=y;
  282.     ExBuf[EBPos+4]=kind;
  283.     EBPos+=5;
  284. };
  285. //[1E][ni][ID:16][kind]
  286. void CmdComplexAttack(byte NI,word ID,byte kind){
  287.     ExBuf[EBPos]=30;
  288.     ExBuf[EBPos+1]=NI;
  289.     *(word*)(&ExBuf[EBPos+2])=ID;
  290.     ExBuf[EBPos+4]=kind;
  291.     EBPos+=5;
  292. };
  293. //[1F][ni][ID:16]
  294. void CmdSendToTransport(byte NI,word ID){
  295.     ExBuf[EBPos]=31;
  296.     ExBuf[EBPos+1]=NI;
  297.     *(word*)(&ExBuf[EBPos+2])=ID;
  298.     EBPos+=4;
  299. };
  300. //[20)][ni][x][y]
  301. void CmdUnload(byte NI,byte x,byte y){
  302.     ExBuf[EBPos]=32;
  303.     ExBuf[EBPos+1]=NI;
  304.     ExBuf[EBPos+2]=x;
  305.     ExBuf[EBPos+3]=y;
  306.     EBPos+=4;
  307. };
  308. //[21][ni]
  309. void CmdDie(byte NI){
  310.     ExBuf[EBPos]=33;
  311.     ExBuf[EBPos+1]=NI;
  312.     EBPos+=2;
  313. };
  314. //[22][ni][x][y]
  315. void CmdContinueAttackPoint(byte NI,byte x,byte y){
  316.     ExBuf[EBPos]=34;
  317.     ExBuf[EBPos+1]=NI;
  318.     ExBuf[EBPos+2]=x;
  319.     ExBuf[EBPos+3]=y;
  320.     EBPos+=4;
  321. };
  322. //[23][ni][x][y]
  323. void CmdContinueAttackWall(byte NI,byte x,byte y){
  324.     ExBuf[EBPos]=35;
  325.     ExBuf[EBPos+1]=NI;
  326.     ExBuf[EBPos+2]=x;
  327.     ExBuf[EBPos+3]=y;
  328.     EBPos+=4;
  329. };
  330. //[24][ni]
  331. void CmdSitDown(byte NI){
  332.     ExBuf[EBPos]=36;
  333.     ExBuf[EBPos+1]=NI;
  334.     EBPos+=2;
  335. };
  336. //[25][ni][x][y]
  337. void CmdNucAtt(byte NI,byte x,byte y){
  338.     ExBuf[EBPos]=37;
  339.     ExBuf[EBPos+1]=NI;
  340.     ExBuf[EBPos+2]=x;
  341.     ExBuf[EBPos+3]=y;
  342.     EBPos+=4;
  343. };
  344. //[26][ni][w:ObjID]
  345. void CmdUnProduceObj(byte NI,word Type){
  346.     ExBuf[EBPos]=38;
  347.     ExBuf[EBPos+1]=NI;
  348.     *(word*)(&ExBuf[EBPos+2])=Type;
  349.     EBPos+=4;
  350. };
  351. //[27][ni][w:ObjID]
  352. void CmdSetRprState(byte NI,byte State){
  353.     ExBuf[EBPos]=39;
  354.     ExBuf[EBPos+1]=NI;
  355.     ExBuf[EBPos+2]=State;
  356.     EBPos+=3;
  357. };
  358. //[28][ni][ID:32][Length:8][Name...]
  359. void CmdSaveNetworkGame(byte NI,int ID,char* Name){
  360.     ExBuf[EBPos]=40;
  361.     ExBuf[EBPos+1]=NI;
  362.     *(int*)(&ExBuf[EBPos+2])=ID;
  363.     byte Len=strlen(Name);
  364.     ExBuf[EBPos+6]=Len;
  365.     strcpy((char*)(&ExBuf[EBPos+7]),Name);
  366.     EBPos+=7+Len;
  367. };
  368. //[2A][ni][ID:32][Length:8][Name...]
  369. void CmdLoadNetworkGame(byte NI,int ID,char* Name){
  370.     ExBuf[EBPos]=41;
  371.     ExBuf[EBPos+1]=NI;
  372.     *(int*)(&ExBuf[EBPos+2])=ID;
  373.     byte Len=strlen(Name);
  374.     ExBuf[EBPos+6]=Len;
  375.     strcpy((char*)(&ExBuf[EBPos+7]),Name);
  376.     EBPos+=7+Len;
  377. };
  378. //[2B][ni][ID]
  379. void CmdChooseSelType(byte NI,word ID){
  380.     ExBuf[EBPos]=42;
  381.     ExBuf[EBPos+1]=NI;
  382.     *(word*)(&ExBuf[EBPos+2])=ID;
  383.     EBPos+=4;
  384. };
  385. //[2C][ni][ID]
  386. void CmdChooseUnSelType(byte NI,word ID){
  387.     ExBuf[EBPos]=43;
  388.     ExBuf[EBPos+1]=NI;
  389.     *(word*)(&ExBuf[EBPos+2])=ID;
  390.     EBPos+=4;
  391. };
  392. void InitSelection(){
  393.     int sz=(MaxObject>>2)+1;
  394.     if(sz>2048)sz=2048;
  395.     __asm{
  396.         push    edi
  397.         mov        ecx,sz
  398.         cld
  399.         xor        eax,eax
  400.         mov        edi,offset CmdDone
  401.         rep        stosd
  402.         pop        edi
  403.     };
  404. };
  405. void CreateSelection(byte NI,byte x,byte y,byte x1,byte y1){
  406.     word MID;
  407.     OneObject* OB;
  408.     word ns=0;
  409.     word Nsel=NSL[NI];
  410.     word* ser=SerN[NI];
  411.     word* SMon=Selm[NI];
  412.     for(int i=0;i<Nsel;i++){
  413.             MID=SMon[i];
  414.             if(MID!=0xFFFF){
  415.                 OB=Group[MID];
  416.                 if(int(OB)&&OB->NNUM==NI&&OB->Serial==ser[i])OB->Selected=false;
  417.             };
  418.     };
  419.     if(int(Selm[NI]))free(Selm[NI]);
  420.     if(int(SerN[NI]))free(SerN[NI]);
  421.     for(i=x;i<=x1;i++)
  422.         for(byte j=y;j<=y1;j++){
  423.             MID=Mops[j][i];
  424.             if(MID!=0xFFFF){
  425.                 OB=Group[MID];
  426.                 if(int(OB)&&OB->NNUM==NI&&OB->Serial==ser[i])ns++;
  427.             };
  428.         };
  429.     word nfs=SelectFly(NI,x,y,x1,y1,NULL,NULL,false);
  430.     Selm[NI]=new word[ns+nfs];
  431.     SerN[NI]=new word[ns+nfs];
  432.     word* SM=Selm[NI];
  433.     word* SN=SerN[NI];
  434.     word ns1=ns;
  435.     ns=0;
  436.     for(i=x;i<=x1;i++)
  437.         for(byte j=y;j<=y1;j++){
  438.             MID=Mops[j][i];
  439.             if(MID!=0xFFFF){
  440.                 OB=Group[MID];
  441.                 if(int(OB)&&OB->NNUM==NI&&!OB->Selected){
  442.                     SM[ns]=MID;
  443.                     SN[ns]=OB->Serial;
  444.                     ns++;
  445.                     OB->Selected=true;
  446.                 };
  447.             };
  448.         };
  449.     SelectFly(NI,x,y,x1,y1,&SM[ns],&SN[ns],true);
  450.     NSL[NI]=ns+nfs;
  451. };
  452. void CreateKindSelection(byte NI,byte x,byte y,byte x1,byte y1,byte Kind){
  453.     word MID;
  454.     OneObject* OB;
  455.     word ns=0;
  456.     word Nsel=NSL[NI];
  457.     word* SMon=Selm[NI];
  458.     for(int i=0;i<Nsel;i++){
  459.             MID=SMon[i];
  460.             if(MID!=0xFFFF){
  461.                 OB=Group[MID];
  462.                 if(int(OB)&&OB->NNUM==NI)OB->Selected=false;
  463.             };
  464.     };
  465.     if(int(Selm[NI]))free(Selm[NI]);
  466.     for(i=x;i<=x1;i++)
  467.         for(byte j=y;j<=y1;j++){
  468.             MID=Mops[j][i];
  469.             if(MID!=0xFFFF){
  470.                 OB=Group[MID];
  471.                 if(int(OB)&&OB->NNUM==NI&&OB->Kind==Kind)ns++;
  472.             };
  473.         };
  474.     Selm[NI]=new word[ns];
  475.     word* SM=Selm[NI];
  476.     ns=0;
  477.     for(i=x;i<=x1;i++)
  478.         for(byte j=y;j<=y1;j++){
  479.             MID=Mops[j][i];
  480.             if(MID!=0xFFFF){
  481.                 OB=Group[MID];
  482.                 if(int(OB)&&OB->NNUM==NI&&(!OB->Selected)&&OB->Kind==Kind){
  483.                     SM[ns]=MID;
  484.                     ns++;
  485.                     OB->Selected=true;
  486.                 };
  487.             };
  488.         };
  489.     NSL[NI]=ns;
  490. };
  491. void CreateTypeSelection(byte NI,byte x,byte y,byte x1,byte y1,word Type){
  492.     word MID;
  493.     OneObject* OB;
  494.     word ns=0;
  495.     word Nsel=NSL[NI];
  496.     word* SMon=Selm[NI];
  497.     for(int i=0;i<Nsel;i++){
  498.             MID=SMon[i];
  499.             if(MID!=0xFFFF){
  500.                 OB=Group[MID];
  501.                 if(int(OB)&&OB->NNUM==NI)OB->Selected=false;
  502.             };
  503.     };
  504.     if(int(Selm[NI]))free(Selm[NI]);
  505.     for(i=x;i<=x1;i++)
  506.         for(byte j=y;j<=y1;j++){
  507.             MID=Mops[j][i];
  508.             if(MID!=0xFFFF){
  509.                 OB=Group[MID];
  510.                 if(int(OB)&&OB->NNUM==NI&&OB->NIndex==Type)ns++;
  511.             };
  512.         };
  513.     Selm[NI]=new word[ns];
  514.     word* SM=Selm[NI];
  515.     ns=0;
  516.     for(i=x;i<=x1;i++)
  517.         for(byte j=y;j<=y1;j++){
  518.             MID=Mops[j][i];
  519.             if(MID!=0xFFFF){
  520.                 OB=Group[MID];
  521.                 if(int(OB)&&OB->NNUM==NI&&(!OB->Selected)&&OB->NIndex==Type){
  522.                     SM[ns]=MID;
  523.                     ns++;
  524.                     OB->Selected=true;
  525.                 };
  526.             };
  527.         };
  528.     NSL[NI]=ns;
  529. };
  530. bool FnKind(OneObject* OB,int N){
  531.     return (OB->Kind==N);
  532. };
  533. bool FnType(OneObject* OB,int N){
  534.     return (OB->NIndex==N);
  535. };
  536. bool PtInside(int x,int y,int x1,int y1,int xp,int yp){
  537.     if(xp>=x&&xp<=x1&&yp>=y&&yp<=y1)return true;
  538.     else return false;
  539. };
  540. void GetRect(OneObject* ZZ,int* x,int* y,int* Lx);
  541. bool ObjInside(OneObject* OB,int xx,int yy,int xx1,int yy1){
  542.     if(!OB)return false;
  543.     int ox,oy,olx;
  544.     GetRect(OB,&ox,&oy,&olx);
  545.     int ox1=ox+olx-1;
  546.     int oy1=oy+olx-1;
  547.     if( PtInside(ox,oy,ox1,oy1,xx,yy)||
  548.         PtInside(ox,oy,ox1,oy1,xx,yy1)||
  549.         PtInside(ox,oy,ox1,oy1,xx1,yy)||
  550.         PtInside(ox,oy,ox1,oy1,xx1,yy1)||
  551.         PtInside(xx,yy,xx1,yy1,ox,oy)||
  552.         PtInside(xx,yy,xx1,yy1,ox1,oy)||
  553.         PtInside(xx,yy,xx1,yy1,ox,oy1)||
  554.         PtInside(xx,yy,xx1,yy1,ox1,oy1))
  555.         return true;
  556.     else return false;
  557. };
  558. word GoodSelectFly(byte NI,int xr,int yr,int xr1,int yr1,word *Collect,word* Ser,bool WRITE,CHOBJ* FN,int NN);
  559. void CreateGoodSelection(byte NI,word xx,word yy,word xx1,word yy1,CHOBJ* FN,int NN,bool Addon){
  560.     int x=xx>>5;
  561.     int y=yy>>5;
  562.     int x1=xx1>>5;
  563.     int y1=yy1>>5;
  564.     if(x>1)x--;
  565.     if(y>1)y--;
  566.     if(x1<msx)x1++;
  567.     if(y1<msy)y1++;
  568.     //if(xx1&31)x1++;
  569.     //if(yy1&31)y1++;
  570.     word MID;
  571.     OneObject* OB;
  572.     word ns=0;
  573.     word Nsel=NSL[NI];
  574.     word* SMon=Selm[NI];
  575.     word* ser=SerN[NI];
  576.     if((!Addon)&&Nsel){
  577.         for(int i=0;i<Nsel;i++){
  578.                 MID=SMon[i];
  579.                 if(MID!=0xFFFF){
  580.                     OB=Group[MID];
  581.                     if(int(OB)&&OB->NNUM==NI&&ser[i]==OB->Serial)OB->Selected=false;
  582.                 };
  583.         };
  584.         if(int(Selm[NI]))free(Selm[NI]);
  585.         if(int(SerN[NI]))free(SerN[NI]);
  586.         Selm[NI]=NULL;
  587.         SerN[NI]=NULL;
  588.     };
  589.     for(int j=y;j<=y1;j++)
  590.         for(int i=x;i<=x1;i++){
  591.             MID=Mops[j][i];
  592.             if(MID!=0xFFFF){
  593.                 OB=Group[MID];
  594.                 if(int(OB)&&OB->NNUM==NI&&((!FN)||(FN&&FN(OB,NN)))&&ObjInside(OB,xx,yy,xx1,yy1))ns++;
  595.             };
  596.         };
  597.     int Olds=0;
  598.     if(Addon)Olds=Nsel;
  599.     word nfs=GoodSelectFly(NI,xx,yy,xx1,yy1,NULL,NULL,false,FN,NN);
  600.     Selm[NI]=new word[Olds+ns+nfs];
  601.     SerN[NI]=new word[Olds+ns+nfs];
  602.     if(Addon&&Nsel){
  603.         memcpy(Selm[NI],SMon,Olds<<1);
  604.         memcpy(SerN[NI],ser,Olds<<1);
  605.     };
  606.     word* SM=Selm[NI];
  607.     word* SR=SerN[NI];
  608.     word ns1=ns;
  609.     ns=Olds;
  610.     for(j=y;j<=y1;j++)
  611.         for(int i=x;i<=x1;i++){
  612.             MID=Mops[j][i];
  613.             if(MID!=0xFFFF){
  614.                 OB=Group[MID];
  615.                 if(int(OB)&&OB->NNUM==NI
  616.                     &&((!FN)||(FN&&FN(OB,NN)))&&ObjInside(OB,xx,yy,xx1,yy1)&&
  617.                     !OB->Selected){
  618.                     SM[ns]=MID;
  619.                     SR[ns]=OB->Serial;
  620.                     ns++;
  621.                     OB->Selected=true;
  622.                 };
  623.             };
  624.         };
  625.     GoodSelectFly(NI,xx,yy,xx1,yy1,&SM[ns],&SR[ns],true,FN,NN);
  626.     NSL[NI]=ns+nfs;
  627.     if(Addon&&Nsel){
  628.         free(SMon);
  629.         free(ser);
  630.     };
  631. };
  632. void RefreshSelected(byte NI){
  633.     int RNSel=0;
  634.     word Nsel=NSL[NI];
  635.     word* SMon=Selm[NI];
  636.     word* ser=SerN[NI];
  637.     if(!Nsel)return;
  638.     word MID;
  639.     for(int k=0;k<Nsel;k++){
  640.         MID=SMon[k];
  641.         if(MID!=0xFFFF){
  642.             OneObject* OB=Group[MID];
  643.             if(OB&&OB->Serial==ser[k]){
  644.                 SMon[RNSel]=SMon[k];
  645.                 ser[RNSel]=ser[k];
  646.                 RNSel++;
  647.             };
  648.         };
  649.     };
  650.     Nsel=RNSel;
  651.     NSL[NI]=Nsel;
  652. };
  653. void SendSelectedToXY(byte NI,byte x,byte y){
  654.     int RNSel=0;
  655.     word Nsel=NSL[NI];
  656.     word* SMon=Selm[NI];
  657.     if(!Nsel)return;
  658.     word MID;
  659.     int Sqs=int(sqrt(Nsel));
  660.     int Glx=Sqs;
  661.     int Gly=Sqs;
  662.     if(Glx*Gly>Nsel)Glx--;
  663.     if(Glx*Gly<Nsel)Glx++;else{
  664.         if(Glx*Gly>Nsel)Gly--;
  665.         if(Glx*Gly<Nsel)Gly++;
  666.     };
  667.     int gx1=x-(Glx>>1);
  668.     int gy1=y-(Gly>>1);
  669.     if(gx1<=0)gx1=1;
  670.     if(gy1<=0)gy1=1;
  671.     if(gx1+Glx>msx)gx1=msx-Glx+1;
  672.     if(gy1+Gly>msy)gy1=msy-Gly+1;
  673.     int zx=gx1;
  674.     int zy=gy1;
  675.     for(int i=0;i<Nsel;i++){
  676.         if(zx-gx1+1>Glx){zx=gx1;zy++;};
  677.         MID=SMon[i];
  678.         if(!(CmdDone[MID]||MID==0xFFFF)&&int(Group[MID]))
  679.             Group[SMon[i]]->SendTo(zx,zy,16);
  680.         zx++;
  681.     };
  682. };
  683. void AttackToXY(byte NI,byte x,byte y){
  684.     word Nsel=NSL[NI];
  685.     word* SMon=Selm[NI];
  686.     if(!Nsel)return;
  687.     word MID;
  688.     int Sqs=int(sqrt(Nsel));
  689.     int Glx=Sqs;
  690.     int Gly=Sqs;
  691.     if(Glx*Gly>Nsel)Glx--;
  692.     if(Glx*Gly<Nsel)Glx++;else{
  693.         if(Glx*Gly>Nsel)Gly--;
  694.         if(Glx*Gly<Nsel)Gly++;
  695.     };
  696.     int gx1=x-(Glx>>1);
  697.     int gy1=y-(Gly>>1);
  698.     if(gx1<=0)gx1=1;
  699.     if(gy1<=0)gy1=1;
  700.     if(gx1+Glx>msx)gx1=msx-Glx+1;
  701.     if(gy1+Gly>msy)gy1=msy-Gly+1;
  702.     int zx=gx1;
  703.     int zy=gy1;
  704.     for(int i=0;i<Nsel;i++){
  705.         if(zx-gx1+1>Glx){zx=gx1;zy++;};
  706.         MID=SMon[i];
  707.         if(!(CmdDone[MID]||MID==0xFFFF)&&int(Group[MID]))
  708.             Group[SMon[i]]->SendTo(zx,zy,129);
  709.         zx++;
  710.     };
  711. };
  712. void AttackSelected(byte NI,word ObjID){
  713.     int RNSel=0;
  714.     word Nsel=NSL[NI];
  715.     word* SMon=Selm[NI];
  716.     if(!Nsel)return;
  717.     word MID;
  718.     for(int i=0;i<Nsel;i++){
  719.         MID=SMon[i];
  720.         if(MID!=0xFFFF&&int(Group[MID]))
  721.             Group[MID]->AttackObj(ObjID,16);
  722.     };
  723. };
  724. void BuildWithSelected(byte NI,word ObjID){
  725.     int RNSel=0;
  726.     word Nsel=NSL[NI];
  727.     word* SMon=Selm[NI];
  728.     if(!Nsel)return;
  729.     word MID;
  730.     for(int i=0;i<Nsel;i++){
  731.         MID=SMon[i];
  732.         if((!(MID==0xFFFF||CmdDone[MID]))&&int(Group[MID]))
  733.             if(Group[MID]->BuildObj(ObjID,16))
  734.                 CmdDone[MID]=true;
  735.     };
  736. };
  737. void CreateTerrainMons(byte NI,byte x,byte y,word Type){
  738.     //NATIONS[NI].CreateTerrainAt(x,y,Type);
  739.     CreateUnit(&NATIONS[NI],x,y,Type);
  740. };
  741. void CreateBuilding(byte NI,byte x,byte y,word Type){
  742.     if(!NATIONS[NI].CheckBuilding(Type,x,y))return;
  743.     int j=NATIONS[NI].CreateBuilding(Type,x,y);
  744.     word Nsel=NSL[NI];
  745.     word* SMon=Selm[NI];
  746.     if(j>=0){
  747.         for(int i=0;i<Nsel;i++){
  748.             word MID=SMon[i];
  749.             if(!(MID==0xFFFF||CmdDone[MID])){
  750.                 OneObject* OBJ=Group[MID];
  751.                 if(OBJ){
  752.                     if(int(OBJ)&&!OBJ->Sdoxlo)
  753.                     if(OBJ->BuildObj(j,16))
  754.                         CmdDone[MID]=true;
  755.                 };
  756.             };
  757.         };
  758.     };
  759. };
  760. void ProduceObject(byte NI,word Type){
  761.     int maxp=1000;
  762.     int kk=-1;
  763.     word Nsel=NSL[NI];
  764.     word* SMon=Selm[NI];
  765.     for(int k=0;k<Nsel;k++){
  766.         word MID=SMon[k];
  767.         if(!(MID==0xFFFF/*||CmdDone[MID]*/)){
  768.             OneObject* OB=Group[SMon[k]];
  769.             if(int(OB)){
  770.                 int pp=OB->CheckAbility(Type);
  771.                 if(pp==-1&&OB->Ready){
  772.                     OB->Produce(Type);
  773.                     CmdDone[MID]=true;
  774.                     return;
  775.                 };
  776.                 if(pp>0&&pp<maxp){
  777.                     maxp=pp;
  778.                     kk=k;
  779.                 };
  780.             };
  781.         };
  782.     };
  783.     if(kk!=-1){
  784.         word MID=SMon[kk];
  785.         if(!(MID==0xFFFF/*||CmdDone[MID]*/)){
  786.             OneObject* OB=Group[MID];
  787.             if(OB){
  788.                 OB->Produce(Type);
  789.                 CmdDone[MID]=true;
  790.             };
  791.         };
  792.     };
  793. };
  794. void UnProduce(OneObject* OB,word Type){
  795.     if(!(OB->capBuilding&&OB->LocalOrder))return;
  796.     Order1* ORR=OB->LocalOrder;
  797.     Order1* POR=NULL;
  798.     do{
  799.         if(ORR->OrderType==13){
  800.             if(ORR->info.Produce.ObjIndex==Type){
  801.                 if(POR){
  802.                     POR->NextOrder=ORR->NextOrder;
  803.                 }else{
  804.                     OB->LocalOrder=ORR->NextOrder;
  805.                 };
  806.                 OB->FreeOrdBlock(ORR);
  807.                 GeneralObject* GO=OB->Nat->Mon[Type];
  808.                 for(int p=0;p<4;p++){
  809.                     int rt=GO->ResourceID[p];
  810.                     if(rt!=255){
  811.                         RESRC[OB->NNUM][rt]+=GO->ResAmount[p];
  812.                     };
  813.                 };
  814.                 return;
  815.             };
  816.         };
  817.         POR=ORR;
  818.         ORR=ORR->NextOrder;
  819.     }while(ORR);
  820. };
  821. void UnProduceObject(byte NI,word Type){
  822.     int maxp=0;
  823.     int kk=-1;
  824.     word Nsel=NSL[NI];
  825.     word* SMon=Selm[NI];
  826.     for(int k=0;k<Nsel;k++){
  827.         word MID=SMon[k];
  828.         if(!(MID==0xFFFF||CmdDone[MID])){
  829.             OneObject* OB=Group[SMon[k]];
  830.             if(int(OB)){
  831.                 int pp=OB->CheckAbility(Type);
  832.                 if(pp>0&&pp>maxp){
  833.                     maxp=pp;
  834.                     kk=k;
  835.                 };
  836.             };
  837.         };
  838.     };
  839.     if(kk!=-1){
  840.         word MID=SMon[kk];
  841.         if(!(MID==0xFFFF||CmdDone[MID])){
  842.             OneObject* OB=Group[MID];
  843.             if(OB){
  844.                 UnProduce(OB,Type);
  845.                 CmdDone[MID]=true;
  846.             };
  847.         };
  848.     };
  849. };
  850. void MemSelection(byte NI,byte Index){
  851.     SelSet[NI*10+Index].CreateFromSelection(NI);    
  852. };
  853. void RememSelection(byte NI,byte Index){
  854.     SelSet[NI*10+Index].SelectMembers(NI);    
  855. };
  856. int CreateWall(byte NI,byte* lp){
  857.     word ci=GWALLS.AddCluster(lp);
  858.     word* dw=(word*)lp;
  859.     int RNSel=0;
  860.     word Nsel=NSL[NI];
  861.     word* SMon=Selm[NI];
  862.     if(!Nsel)return (dw[1]<<1)+5;
  863.     word MID;
  864.     for(int i=0;i<Nsel;i++){
  865.         MID=SMon[i];
  866.         if(!(MID==0xFFFF||CmdDone[MID])){
  867.             OneObject* OB=Group[MID];
  868.             if(OB&&OB->BuildWall(ci,16))CmdDone[MID]=true;
  869.         };
  870.     };
  871.     return (dw[1]<<1)+5;
  872. };
  873. void RepairWall(byte NI,word ci){
  874.     int RNSel=0;
  875.     word Nsel=NSL[NI];
  876.     word* SMon=Selm[NI];
  877.     if(!Nsel)return;
  878.     word MID;
  879.     for(int i=0;i<Nsel;i++){
  880.         MID=SMon[i];
  881.         if(!(MID==0xFFFF||CmdDone[MID])){
  882.             OneObject* OB=Group[MID];
  883.             if(OB&&OB->BuildWall(ci,16))CmdDone[MID]=true;
  884.         };
  885.     };
  886. };
  887. void DamageWall(byte NI,word ci){
  888.     int RNSel=0;
  889.     word Nsel=NSL[NI];
  890.     word* SMon=Selm[NI];
  891.     if(!Nsel)return;
  892.     word MID;
  893.     for(int i=0;i<Nsel;i++){
  894.         MID=SMon[i];
  895.         if(!(MID==0xFFFF||CmdDone[MID])){
  896.             OneObject* OB=Group[MID];
  897.             if(OB&&OB->DamageWall(ci,16))CmdDone[MID]=true;
  898.         };
  899.     };
  900. };
  901. void TakeRes(byte NI,byte x,byte y,byte ResID){
  902. int RNSel=0;
  903.     word Nsel=NSL[NI];
  904.     word* SMon=Selm[NI];
  905.     if(!Nsel)return;
  906.     word MID;
  907.     for(int i=0;i<Nsel;i++){
  908.         MID=SMon[i];
  909.         if(!(MID==0xFFFF&&CmdDone[MID])){
  910.             OneObject* OB=Group[MID];
  911.             if(OB&&OB->TakeResource(x,y,ResID,16))CmdDone[MID]=true;
  912.         };
  913.     };
  914. };
  915. void GetOil(byte NI,word OID){
  916. int RNSel=0;
  917.     word Nsel=NSL[NI];
  918.     word* SMon=Selm[NI];
  919.     if(!Nsel)return;
  920.     word MID;
  921.     for(int i=0;i<Nsel;i++){
  922.         MID=SMon[i];
  923.         if(!(MID==0xFFFF&&CmdDone[MID])){
  924.             OneObject* OB=Group[MID];
  925.             if(OB&&OB->GetOil(OID,16))CmdDone[MID]=true;
  926.         };
  927.     };
  928. };
  929. void PerformUpgr(byte NI,word UI){
  930.     word Nsel=NSL[NI];
  931.     word* SMon=Selm[NI];
  932.     if(!Nsel)return;
  933.     word MID;
  934.     for(int i=0;i<Nsel;i++){
  935.         MID=SMon[i];
  936.         if(MID!=0xFFFF&&int(Group[MID]))
  937.             Group[SMon[i]]->PerformUpgrade(UI);
  938.     };
  939. };
  940. void SendToPoint(byte NI,byte x,byte y){
  941.     int RNSel=0;
  942.     word Nsel=NSL[NI];
  943.     word* SMon=Selm[NI];
  944.     if(!Nsel)return;
  945.     word MID;
  946.     for(int i=0;i<Nsel;i++){
  947.         MID=SMon[i];
  948.         if(MID!=0xFFFF&&int(Group[MID]))
  949.             Group[MID]->SendTo(x,y,16);
  950.     };
  951. };
  952. void SetDestination(byte NI,byte x,byte y){
  953.     int RNSel=0;
  954.     word Nsel=NSL[NI];
  955.     word* SMon=Selm[NI];
  956.     if(!Nsel)return;
  957.     word MID;
  958.     for(int i=0;i<Nsel;i++){
  959.         MID=SMon[i];
  960.         if(MID!=0xFFFF&&int(Group[MID]))
  961.             Group[MID]->SetDstPoint(x,y);
  962.     };
  963. };
  964. void Stopp(byte NI){
  965.     int RNSel=0;
  966.     word Nsel=NSL[NI];
  967.     word* SMon=Selm[NI];
  968.     if(!Nsel)return;
  969.     word MID;
  970.     for(int i=0;i<Nsel;i++){
  971.         MID=SMon[i];
  972.         if(MID!=0xFFFF&&int(Group[MID])){
  973.             OneObject* OB=Group[MID];
  974.             if(OB){
  975.                 OB->ClearOrders();
  976.                 OB->LoadAnimation(0,OB->AnmStandKind,0);
  977.                 OB->LoadCurAnm(0);
  978.             };
  979.         };
  980.     };
  981. };
  982. void StandGround(byte NI){
  983.     int RNSel=0;
  984.     word Nsel=NSL[NI];
  985.     word* SMon=Selm[NI];
  986.     if(!Nsel)return;
  987.     word MID;
  988.     for(int i=0;i<Nsel;i++){
  989.         MID=SMon[i];
  990.         if(MID!=0xFFFF&&int(Group[MID])){
  991.             OneObject* OB=Group[MID];
  992.             OB->StandGround=true;
  993.             if(!OB->Media){
  994.                 TrMap[OB->y][OB->x]=1;
  995.             }else if (OB->Media==1){
  996.                 WMap[OB->y][OB->x]=1;
  997.             };
  998.         };
  999.     };
  1000. };
  1001. void PatrolGroup(byte NI,byte x1,byte y1){
  1002.     int RNSel=0;
  1003.     word Nsel=NSL[NI];
  1004.     word* SMon=Selm[NI];
  1005.     if(!Nsel)return;
  1006.     word MID;
  1007.     for(int i=0;i<Nsel;i++){
  1008.         MID=SMon[i];
  1009.         if(MID!=0xFFFF&&int(Group[MID])){
  1010.             OneObject* OB=Group[MID];
  1011.             if(OB)OB->Patrol(OB->x,OB->y,x1,y1,0);
  1012.         };
  1013.     };
  1014. };
  1015. void GroupAttackPoint(byte NI,byte x,byte y,byte kind){
  1016.     int RNSel=0;
  1017.     word Nsel=NSL[NI];
  1018.     word* SMon=Selm[NI];
  1019.     if(!Nsel)return;
  1020.     word MID;
  1021.     for(int i=0;i<Nsel;i++){
  1022.         MID=SMon[i];
  1023.         if(MID!=0xFFFF&&int(Group[MID])){
  1024.             OneObject* OB=Group[MID];
  1025.             if(OB)OB->AttackPoint(x,y,kind,16);
  1026.         };
  1027.     };
  1028. };
  1029. void SendToTransp(byte NI,word ID){
  1030.     int RNSel=0;
  1031.     word Nsel=NSL[NI];
  1032.     word* SMon=Selm[NI];
  1033.     if(!Nsel)return;
  1034.     word MID;
  1035.     for(int i=0;i<Nsel;i++){
  1036.         MID=SMon[i];
  1037.         if(MID!=0xFFFF&&int(Group[MID])){
  1038.             OneObject* OB=Group[MID];
  1039.             if(OB)OB->GoToTransport(ID,16);
  1040.         };
  1041.     };
  1042. };
  1043. void UnloadTransp(byte NI,byte x1,byte y1){
  1044.     int RNSel=0;
  1045.     word Nsel=NSL[NI];
  1046.     word* SMon=Selm[NI];
  1047.     if(!Nsel)return;
  1048.     word MID;
  1049.     for(int i=0;i<Nsel;i++){
  1050.         MID=SMon[i];
  1051.         if(MID!=0xFFFF&&int(Group[MID])){
  1052.             OneObject* OB=Group[MID];
  1053.             if(OB)OB->UnloadPassangers(x1,y1);
  1054.         };
  1055.     };
  1056. };
  1057. void GroupComplexAttack(byte NI,word ID,byte kind){
  1058.     int RNSel=0;
  1059.     word Nsel=NSL[NI];
  1060.     word* SMon=Selm[NI];
  1061.     if(!Nsel)return;
  1062.     word MID;
  1063.     for(int i=0;i<Nsel;i++){
  1064.         MID=SMon[i];
  1065.         if(MID!=0xFFFF&&int(Group[MID])){
  1066.             OneObject* OB=Group[MID];
  1067.             if(OB)OB->ComplexAttack(ID,kind,16);
  1068.         };
  1069.     };
  1070. };
  1071. void DieSelected(byte NI){
  1072.     int RNSel=0;
  1073.     word Nsel=NSL[NI];
  1074.     word* SMon=Selm[NI];
  1075.     if(!Nsel)return;
  1076.     word MID;
  1077.     for(int i=0;i<Nsel;i++){
  1078.         MID=SMon[i];
  1079.         if(MID!=0xFFFF&&int(Group[MID])){
  1080.             OneObject* OB=Group[MID];
  1081.             if(OB){
  1082.                 OB->InFire=true;
  1083.                 OB->Die();
  1084.             };
  1085.         };
  1086.     };
  1087. };
  1088. void ContinueAttPoint(byte NI,byte x,byte y){
  1089.     int RNSel=0;
  1090.     word Nsel=NSL[NI];
  1091.     word* SMon=Selm[NI];
  1092.     if(!Nsel)return;
  1093.     word MID;
  1094.     for(int i=0;i<Nsel;i++){
  1095.         MID=SMon[i];
  1096.         if(MID!=0xFFFF&&int(Group[MID]))
  1097.             Group[MID]->ContinueAttackPoint(x,y,16);
  1098.     };
  1099. };
  1100. void ContinueAttWall(byte NI,byte x,byte y){
  1101.     int RNSel=0;
  1102.     word Nsel=NSL[NI];
  1103.     word* SMon=Selm[NI];
  1104.     if(!Nsel)return;
  1105.     word MID;
  1106.     for(int i=0;i<Nsel;i++){
  1107.         MID=SMon[i];
  1108.         if(MID!=0xFFFF&&int(Group[MID]))
  1109.             Group[MID]->ContinueAttackWall(x,y,16);
  1110.     };
  1111. };
  1112. void SitDown(byte NI){
  1113.     int RNSel=0;
  1114.     word Nsel=NSL[NI];
  1115.     word* SMon=Selm[NI];
  1116.     if(!Nsel)return;
  1117.     word MID;
  1118.     for(int i=0;i<Nsel;i++){
  1119.         MID=SMon[i];
  1120.         if(MID!=0xFFFF&&int(Group[MID])){
  1121.             OneObject* OB=Group[MID];
  1122.             if(OB)OB->MakeMeSit();
  1123.         };
  1124.     };
  1125. };
  1126. void UseNuclo(byte NI,byte x,byte y){
  1127.     int RNSel=0;
  1128.     word Nsel=NSL[NI];
  1129.     word* SMon=Selm[NI];
  1130.     if(!Nsel)return;
  1131.     word MID;
  1132.     for(int i=0;i<Nsel;i++){
  1133.         MID=SMon[i];
  1134.         if(MID!=0xFFFF&&int(Group[MID]))
  1135.             Group[MID]->NuclearAttack(x,y);
  1136.     };
  1137. };
  1138. void SetRepairState(byte NI,byte state){
  1139.     int RNSel=0;
  1140.     word Nsel=NSL[NI];
  1141.     word* SMon=Selm[NI];
  1142.     if(!Nsel)return;
  1143.     word MID;
  1144.     for(int i=0;i<Nsel;i++){
  1145.         MID=SMon[i];
  1146.         if(MID!=0xFFFF&&int(Group[MID])){
  1147.             OneObject* OB=Group[MID];
  1148.             if(OB&&OB->Ref.General->CanRepair)OB->Repair=state;
  1149.         };
  1150.     };
  1151. };
  1152. //*******************************************************************************//
  1153. //****************                                                 **************//
  1154. //*******                          SAVING IPX GAME                         ******//
  1155. //****************                                                 **************//
  1156. //*******************************************************************************//
  1157. void LoadGame(char* fnm);
  1158. void SaveGame(char* fnm,char* Messtr,int ID);
  1159. #define MaxSFNames 128
  1160. extern int sfVersion;
  1161. static int   NSFNames;
  1162. char* SFNames[MaxSFNames];
  1163. char* PLNames[MaxSFNames];
  1164. int   PLID[MaxSFNames];
  1165. //1. Creating list of save files
  1166. void ClearSFNames(){
  1167.     for(int i=0;i<NSFNames;i++){
  1168.         free(SFNames[i]);
  1169.         free(PLNames[i]);
  1170.     };
  1171.     NSFNames=0;
  1172. };
  1173. void InstallSFName(WIN32_FIND_DATA* FD){
  1174.     ResFile ff1=RReset(FD->cFileName);
  1175.     char nam[128];
  1176.     if(!IOresult()){
  1177.         int sig,lap;
  1178.         RBlockRead(ff1,&sig,4);
  1179.         if(sig=='WSF2'){
  1180.             RBlockRead(ff1,&sig,4);
  1181.             RBlockRead(ff1,&lap,4);
  1182.             if(sig==sfVersion&&NSFNames<MaxSFNames){
  1183.                 int nlen=0;
  1184.                 RBlockRead(ff1,&nlen,2);
  1185.                 nlen=0;
  1186.                 RBlockRead(ff1,&nlen,1);
  1187.                 RBlockRead(ff1,nam,nlen);
  1188.                 RClose(ff1);
  1189.                 PLNames[NSFNames]=new char[strlen(nam)+1];
  1190.                 SFNames[NSFNames]=new char[strlen(FD->cFileName)+1];
  1191.                 PLID[NSFNames]=lap;
  1192.                 strcpy(PLNames[NSFNames],nam);
  1193.                 strcpy(SFNames[NSFNames],FD->cFileName);
  1194.                 NSFNames++;
  1195.             }else RClose(ff1);
  1196.         }else RClose(ff1);
  1197.     };
  1198. };
  1199. void CreateSFList(){
  1200.     NSFNames=0;
  1201.     WIN32_FIND_DATA FD;
  1202.     HANDLE HF=FindFirstFile("*.sav",&FD);
  1203.     if(HF!=INVALID_HANDLE_VALUE){
  1204.         InstallSFName(&FD);
  1205.         while(FindNextFile(HF,&FD))InstallSFName(&FD);
  1206.     };
  1207. };
  1208. //2. Search for name of the game,returns -1 if name not found
  1209. int FindPLName(char* Name){
  1210.     for(int i=0;i<NSFNames;i++){
  1211.         if(!strcmp(PLNames[i],Name))return i;
  1212.     };
  1213.     return -1;
  1214. };
  1215. //2. Search for name of the save file,returns -1 if name not found
  1216. int FindSFName(char* SName){
  1217.     for(int i=0;i<NSFNames;i++){
  1218.         if(!strcmp(SFNames[i],SName))return i;
  1219.     };
  1220.     return -1;
  1221. };
  1222. //Searching for the best name of the save file with the given name
  1223. void FindBestSFName(char* SName,char* Name){
  1224.     int i=FindPLName(Name);
  1225.     if(i==-1){
  1226.         int j=0;
  1227.         char fname[128]="";
  1228.         do{
  1229.             sprintf(fname,"save%d.sav",j);
  1230.             i=FindSFName(fname);
  1231.             if(i==-1){
  1232.                 strcpy(SName,fname);
  1233.                 return;
  1234.             };
  1235.             j++;
  1236.         }while(true);
  1237.     }else{
  1238.         strcpy(SName,SFNames[i]);
  1239.         return;
  1240.     };
  1241. };
  1242. void SaveNetworkGame(byte NI,int ID,char* Name){
  1243.     CreateSFList();
  1244.     char fname[128];
  1245.     FindBestSFName(fname,Name);
  1246.     SaveGame(fname,Name,ID);
  1247.     ClearSFNames();
  1248. };
  1249. int FindNetGame(int ID,char* name){
  1250.     for(int i=0;i<NSFNames;i++){
  1251.         if(PLID[i]==ID&&!strcmp(name,PLNames[i]))return i;
  1252.     };
  1253.     return -1;
  1254. };
  1255. void IAmLeft();
  1256. void LoadNetworkGame(byte NI,int ID,char* Name){
  1257.     CreateSFList();
  1258.     int i=FindNetGame(ID,Name);
  1259.     if(i!=-1){
  1260.         LoadGame(SFNames[i]);
  1261.     }else{
  1262.         IAmLeft();
  1263.     };
  1264.     ClearSFNames();
  1265. };
  1266. void ChooseUnSelectType(byte NI,word ID){
  1267.     int RNSel=0;
  1268.     word Nsel=NSL[NI];
  1269.     word* SMon=Selm[NI];
  1270.     word* SNM=SerN[NI];
  1271.     if(!Nsel)return;
  1272.     word MID;
  1273.     for(int i=0;i<Nsel;i++){
  1274.         MID=SMon[i];
  1275.         if(MID!=0xFFFF){
  1276.             OneObject* OB=Group[MID];
  1277.             if(OB&&OB->NIndex!=ID){
  1278.                 SMon[RNSel]=SMon[i];
  1279.                 SNM[RNSel]=SNM[i];
  1280.                 RNSel++;
  1281.             }else{
  1282.                 OB->Selected=false;
  1283.             };
  1284.         };
  1285.     };
  1286.     NSL[NI]=RNSel;
  1287. };
  1288. void ChooseSelectType(byte NI,word ID){
  1289.     int RNSel=0;
  1290.     word Nsel=NSL[NI];
  1291.     word* SMon=Selm[NI];
  1292.     word* SNM=SerN[NI];
  1293.     if(!Nsel)return;
  1294.     word MID;
  1295.     for(int i=0;i<Nsel;i++){
  1296.         MID=SMon[i];
  1297.         if(MID!=0xFFFF){
  1298.             OneObject* OB=Group[MID];
  1299.             if(OB&&OB->NIndex==ID){
  1300.                 SMon[RNSel]=SMon[i];
  1301.                 SNM[RNSel]=SNM[i];
  1302.                 RNSel++;
  1303.             }else{
  1304.                 OB->Selected=false;
  1305.             };
  1306.         };
  1307.     };
  1308.     NSL[NI]=RNSel;
  1309. };
  1310. void ExecuteBuffer(){
  1311.     InitSelection();
  1312.     for(int p=0;p<8;p++)RefreshSelected(p);
  1313.     int pos=0;
  1314.     int len;
  1315.     char sss[128];
  1316.     while(pos<EBPos){
  1317.         byte cmd=ExBuf[pos];
  1318.         pos++;
  1319.         switch(cmd){
  1320.         case 1://Create selection
  1321.             CreateSelection(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2],
  1322.                 ExBuf[pos+3],ExBuf[pos+4]);
  1323.             pos+=5;
  1324.             break;
  1325.         case 2://Send group to (X,Y)
  1326.             SendSelectedToXY(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1327.             pos+=3;
  1328.             break;
  1329.         case 3://Attack object with group
  1330.             AttackSelected(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1331.             pos+=3;
  1332.             break;
  1333.         case 4://Create terrain object
  1334.             CreateTerrainMons(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2],
  1335.                 *(word*)(&ExBuf[pos+3]));
  1336.             pos+=5;
  1337.             break;
  1338.         case 5://create building
  1339.             CreateBuilding(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2],
  1340.                 *(word*)(&ExBuf[pos+3]));
  1341.             pos+=5;
  1342.             break;
  1343.         case 6://produce object
  1344.             ProduceObject(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1345.             pos+=3;
  1346.             break;
  1347.         case 7://member selection
  1348.             MemSelection(ExBuf[pos],ExBuf[pos+1]);
  1349.             pos+=2;
  1350.             break;
  1351.         case 8://remember selection
  1352.             RememSelection(ExBuf[pos],ExBuf[pos+1]);
  1353.             pos+=2;
  1354.             break;
  1355.         case 9://build or repair object
  1356.             BuildWithSelected(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1357.             pos+=3;
  1358.             break;
  1359.         case 10:
  1360.             pos+=CreateWall(ExBuf[pos],&ExBuf[pos+1]);
  1361.             break;
  1362.         case 11:
  1363.             RepairWall(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1364.             pos+=3;
  1365.             break;
  1366.         case 12:
  1367.             DamageWall(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1368.             pos+=3;
  1369.             break;
  1370.         case 13:
  1371.             TakeRes(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2],ExBuf[pos+3]);
  1372.             pos+=4;
  1373.             break;
  1374.         case 14:
  1375.             PerformUpgr(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1376.             pos+=3;
  1377.             break;
  1378.         case 15:
  1379.             GetOil(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1380.             pos+=3;
  1381.             break;
  1382.         case 16://Create kind selection
  1383.             CreateKindSelection(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2],
  1384.                 ExBuf[pos+3],ExBuf[pos+4],ExBuf[pos+5]);
  1385.             pos+=6;
  1386.             break;
  1387.         case 17://Create type selection
  1388.             CreateTypeSelection(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2],
  1389.                 ExBuf[pos+3],ExBuf[pos+4],*(word*)(&ExBuf[pos+5]));
  1390.             pos+=7;
  1391.             break;
  1392.         case 18://good selection
  1393.             CreateGoodSelection(ExBuf[pos],
  1394.                 *(word*)(&ExBuf[pos+1]),
  1395.                 *(word*)(&ExBuf[pos+3]),
  1396.                 *(word*)(&ExBuf[pos+5]),
  1397.                 *(word*)(&ExBuf[pos+7]),
  1398.                 NULL,0,ExBuf[pos+9]);
  1399.             pos+=10;
  1400.             break;
  1401.         case 19://good kind selection
  1402.             CreateGoodSelection(ExBuf[pos],
  1403.                 *(word*)(&ExBuf[pos+1]),
  1404.                 *(word*)(&ExBuf[pos+3]),
  1405.                 *(word*)(&ExBuf[pos+5]),
  1406.                 *(word*)(&ExBuf[pos+7]),
  1407.                 &FnKind,ExBuf[pos+9],ExBuf[pos+10]);
  1408.             pos+=11;
  1409.             break;
  1410.         case 20://good type selection
  1411.             CreateGoodSelection(ExBuf[pos],
  1412.                 *(word*)(&ExBuf[pos+1]),
  1413.                 *(word*)(&ExBuf[pos+3]),
  1414.                 *(word*)(&ExBuf[pos+5]),
  1415.                 *(word*)(&ExBuf[pos+7]),
  1416.                 &FnType,*(word*)(&ExBuf[pos+9]),ExBuf[pos+11]);
  1417.             pos+=12;
  1418.             break;
  1419.         case 21://set destination
  1420.             SetDestination(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1421.             pos+=3;
  1422.             break;
  1423.         case 22://send to point
  1424.             SendToPoint(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1425.             pos+=3;
  1426.             break;
  1427.         case 23://Send group to (X,Y)
  1428.             AttackToXY(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1429.             pos+=3;
  1430.             break;
  1431.         case 24://STOP
  1432.             Stopp(ExBuf[pos]);
  1433.             pos++;
  1434.             break;
  1435.         case 25://STAND GROUND
  1436.             StandGround(ExBuf[pos]);
  1437.             pos++;
  1438.             break;
  1439.         case 26://Patrol
  1440.             PatrolGroup(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1441.             pos+=3;
  1442.             break;
  1443.         case 28://
  1444.             break;
  1445.         case 29://Complex attack point
  1446.             GroupAttackPoint(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2],ExBuf[pos+3]);
  1447.             pos+=4;
  1448.             break;
  1449.         case 30://Complex attack object
  1450.             GroupComplexAttack(ExBuf[pos],*(word*)(&ExBuf[pos+1]),ExBuf[pos+3]);
  1451.             pos+=4;
  1452.             break;
  1453.         case 31://GoToTransport
  1454.             SendToTransp(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1455.             pos+=3;
  1456.             break;
  1457.         case 32://Unload Transport
  1458.             UnloadTransp(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1459.             pos+=3;
  1460.             break;
  1461.         case 33://Die selected
  1462.             DieSelected(ExBuf[pos]);
  1463.             pos++;
  1464.             break;
  1465.         case 34://attack point
  1466.             ContinueAttPoint(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1467.             pos+=3;
  1468.             break;
  1469.         case 35://attack point
  1470.             ContinueAttWall(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1471.             pos+=3;
  1472.             break;
  1473.         case 36://sit down
  1474.             SitDown(ExBuf[pos]);
  1475.             pos++;
  1476.             break;
  1477.         case 37:
  1478.             UseNuclo(ExBuf[pos],ExBuf[pos+1],ExBuf[pos+2]);
  1479.             pos+=3;
  1480.             break;
  1481.         case 38://produce object
  1482.             UnProduceObject(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1483.             pos+=3;
  1484.             break;
  1485.         case 39:
  1486.             SetRepairState(ExBuf[pos],ExBuf[pos+1]);
  1487.             pos+=2;
  1488.             break;
  1489.         case 40://save network game
  1490.             len=ExBuf[pos+5];
  1491.             memcpy(sss,&ExBuf[pos+6],len);
  1492.             sss[len]=0;
  1493.             SaveNetworkGame(ExBuf[pos],*(int*)(&ExBuf[pos+1]),sss);
  1494.             pos+=6+len;
  1495.             break;
  1496.         case 41://load network game
  1497.             len=ExBuf[pos+5];
  1498.             memcpy(sss,&ExBuf[pos+6],len);
  1499.             sss[len]=0;
  1500.             LoadNetworkGame(ExBuf[pos],*(int*)(&ExBuf[pos+1]),sss);
  1501.             tmtmt=0;
  1502.             rpos=0;
  1503.             pos+=len+6;
  1504.             break;
  1505.         case 42://select type
  1506.             ChooseSelectType(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1507.             pos+=3;
  1508.             break;
  1509.         case 43://select type
  1510.             ChooseUnSelectType(ExBuf[pos],*(word*)(&ExBuf[pos+1]));
  1511.             pos+=3;
  1512.             break;
  1513.         };
  1514.     };
  1515.     InitEBuf();
  1516.     memset(&NPresence[0][0],0,sizeof NPresence);
  1517.     for(int i=0;i<MaxObject;i++){
  1518.         OneObject* OB=Group[i];
  1519.         if(OB)NPresence[OB->y>>2][OB->x>>2]|=OB->NMask;
  1520.     };
  1521. };