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

  1. /* Properties of the selected objects viewering and *
  2.  * corresponding mouse handling                     */
  3. #include "ddini.h"
  4. #include "ResFile.h"
  5. #include "FastDraw.h"
  6. #include "mgraph.h"
  7. #include "mouse.h"
  8. #include "menu.h"
  9. #include "MapDiscr.h"
  10. #include "mode.h"
  11. #include "Nature.h"
  12. #include "fonts.h"
  13. #include "TopZones.h"
  14. #include "walls.h"
  15. #include "Megapolis.h"
  16. #include "GSound.h"
  17. #define MaxO 64
  18. void AssignHint1(char* s,int time);
  19. bool SelSoundDobe;
  20. bool SelSoundReady;
  21. int SelSoundType;
  22. word GetOwner(int x,int y);
  23. int CreateRZone(int x,int y,int lx,int ly,HandlePro* HPro,HandlePro* RHPro,int Index,char* Hint);
  24. extern byte fon000[1024*768];
  25. int PrpX;
  26. int PrpY;
  27. int PrpNx;
  28. int PrpNy;
  29. int AblX;
  30. int AblY;
  31. int AblNx;
  32. int AblNy;
  33. static bool PropClean=false;
  34. static bool AbltClean=false;
  35. int IconLx;
  36. int IconLy;
  37. struct MonInf{
  38.     GeneralObject* RF;
  39.     int Life;
  40.     int MaxLife;
  41.     int Magic;
  42.     int MaxMag;
  43.     int N;
  44.     word Last;
  45.     word ID;
  46. };
  47. struct AblInf{
  48.     Nation* NT;
  49.     word OInd;
  50.     word Kind;
  51.     word UPIND;
  52. };
  53. bool FindResource(byte* xx,byte* yy,byte Radius,byte kind,ZType zz);
  54. MonInf MList[MaxO];
  55. AblInf AList[MaxO];
  56. int GetProgress(word ID);
  57. int GetAmount(word ID);
  58. int SubIcon;
  59. static GeneralObject* LastGO;
  60. static Nation* LastNT;
  61. static word LastAmount;
  62. static word LastID;
  63. extern int curptr;
  64. extern int curdx;
  65. extern int curdy;
  66. //uniq properties
  67. bool GetCoord;
  68. UniqMethood* UNIM;
  69. void InitPrpBar(){
  70.     PrpNx=4;
  71.     PrpNy=2;
  72.     PrpX=10;
  73.     PrpY=(msy>>1)+miniy+16;
  74.     AblX=PrpX;
  75.     AblY=PrpY+PrpNy*IconLy+16;
  76.     AblNx=PrpNx;
  77.     AblNy=6;
  78.     SubIcon=-1;
  79. };
  80. void ResFon(int x,int y,int Lx,int Ly){
  81.     int x1=(x&(65535-3));
  82.     int lx=((x+Lx+4)&(65535-3))-x1;
  83.     int StDy=SCRSizeX-lx;
  84.     int FONDy=COPYSizeX-lx;
  85.     int DsOf=int(ScreenPtr)+x1+y*SCRSizeX;
  86.     int SrOf=int(fon000)+x1+y*COPYSizeX;
  87.     int lx1=lx>>2;
  88.     __asm{
  89.         push    esi
  90.         push    edi
  91.         cld
  92.         mov        eax,Ly
  93.         mov        esi,SrOf
  94.         mov        edi,DsOf
  95.         mov        ebx,StDy
  96. jj1:    mov        ecx,lx1
  97.         rep        movsd
  98.         add        esi,FONDy
  99.         add        edi,ebx
  100.         dec        eax    
  101.         jnz        jj1
  102.     };
  103. };
  104. void ScrCopy(int x,int y,int Lx,int Ly){
  105.     //if(DDebug){
  106. //
  107. //        return;
  108. //    };
  109.     int x1=(x&(65535-3));
  110.     int lx=((x+Lx+4)&(65535-3))-x1;
  111.     int StDy=RSCRSizeX-lx;
  112.     int FONDy=SCRSizeX-lx;
  113.     int DsOf=int(RealScreenPtr)+x1+y*RSCRSizeX;
  114.     int SrOf=int(ScreenPtr)+x1+y*SCRSizeX;
  115.     int lx1=lx>>2;
  116.     __asm{
  117.         push    esi
  118.         push    edi
  119.         cld
  120.         mov        eax,Ly
  121.         mov        esi,SrOf
  122.         mov        edi,DsOf
  123.         mov        ebx,StDy
  124. jj1:    mov        ecx,lx1
  125.         rep        movsd
  126.         add        esi,FONDy
  127.         add        edi,ebx
  128.         dec        eax    
  129.         jnz        jj1
  130.     };
  131. };
  132. int NINF,NABL;
  133. void GeneralObject::GetMonsterCostString(char* st){
  134.     char uu[128];
  135.     for(int i=0;i<4;i++){
  136.         if(ResourceID[i]!=255){
  137.             sprintf(uu," %s : %d",RDS[ResourceID[i]].Name,int(ResAmount[i]));
  138.             if(i>0){
  139.                 strcat(st,",");
  140.                 strcat(st,uu);
  141.             }else {
  142.                 strcat(st," ");
  143.                 strcat(st,uu);
  144.             };
  145.         };
  146.     };
  147. };
  148. void Nation::GetUpgradeCostString(char* st,word UI){
  149.     char uu[128];
  150.     sprintf(uu," %s : %d",RDS[1].Name,int(UPG.utp[UI]->Cost));
  151.     strcat(st,uu);
  152. };
  153. void HPSEL(int i){
  154.     if(GetKeyState(VK_SHIFT)&0x8000){
  155.         CmdChooseUnSelType(MyNation,i);
  156.     }else{
  157.         CmdChooseSelType(MyNation,i);
  158.     };
  159. };
  160. void ShowProp(){
  161.     NINF=0;
  162.     InitZones();
  163.     word MID;
  164.     OneObject* OBJ;
  165.     GeneralObject* GO;
  166.     MonInf* MI;
  167.     int i,j;
  168.     //ResFon(PrpX,PrpY,PrpNx*IconLx,PrpNy*IconLy);
  169.     word Nsel=NSL[MyNation];
  170.     word* SMon=Selm[MyNation];
  171.     if(!Nsel)return;
  172.     if(SelSoundReady){
  173.         if(SMon[0]!=0xFFFF){
  174.             OneObject* OB=Group[SMon[0]];
  175.             if(OB){
  176.                 if(SelSoundType)AddOrderEffect(OB->x,OB->y,OB->Ref.General->OrderSound);
  177.                 else AddOrderEffect(OB->x,OB->y,OB->Ref.General->ClickSound);
  178.                 SelSoundReady=false;
  179.             };
  180.         };
  181.     };
  182.     for(i=0;i<Nsel;i++){
  183.         MID=SMon[i];
  184.         if(MID!=0xFFFF){
  185.             OBJ=Group[MID];
  186.             if(int(OBJ)&&!OBJ->Sdoxlo){
  187.                 GO=OBJ->Ref.General;
  188.                 for(j=0;j<NINF;j++){
  189.                     if(GO==MList[j].RF)break;
  190.                 };
  191.                 MI=&(MList[j]);
  192.                 if(j>=NINF){
  193.                     MI->Life=0;
  194.                     MI->MaxLife=0;
  195.                     MI->Magic=0;
  196.                     MI->MaxMag=0;
  197.                     MI->N=0;
  198.                     NINF=j+1;
  199.                     MI->Last=0;
  200.                     MI->ID=0;
  201.                 };
  202.                 MI->RF=GO;
  203.                 MI->Life+=OBJ->Life;
  204.                 MI->MaxLife+=OBJ->MaxLife;
  205.                 //MI->Magic+=OBJ->Magic;
  206.                 if(MI->MaxMag<OBJ->Magic)MI->MaxMag=OBJ->Magic;
  207.                 MI->Magic=MI->MaxMag;
  208.                 MI->N++;
  209.                 if(MI->N==1&&!OBJ->Ready)MI->Last=MID;
  210.                 if(OBJ->Ready)MI->Last=MID;
  211.                 MI->ID=OBJ->NIndex;
  212.             };
  213.         };
  214.     };
  215.     int PN=PrpNx*PrpNy;
  216.     if(NINF>PN)NINF=PN;
  217.     int xx=0;
  218.     int x1=PrpX;
  219.     int y1=PrpY;
  220.     OneSlide* OC;
  221.     char str[32];
  222.     for(i=0;i<NINF;i++){
  223.         MI=&(MList[i]);
  224.         OBJ=Group[MI->Last];
  225.         OBJ->LoadAnimation(3,0,0);
  226.         OBJ->LoadAnimation(3,8,0);
  227.         OC=OBJ->ARegs[3].Anm[0].Movie;
  228.         ShowRLCItem(x1,y1,&MImage[OC->FileID],OC->spr,MyNation);
  229.         Xbar(x1,y1,IconLx-2,IconLy-2,15);
  230.         Hline(x1+1,y1+IconLy-6,x1+IconLx-4,15);
  231.         int HL;
  232.         if(MI->MaxLife>0) HL=div(MI->Life*(IconLx-4),MI->MaxLife).quot;
  233.         else HL=0;
  234.         MI->Magic=div(MI->Magic,NINF).quot;
  235.         Hline(x1+1,y1+IconLy-5,x1+HL,255);
  236.         Hline(x1+1,y1+IconLy-4,x1+HL,255);
  237.         sprintf(str,"%d",MI->N);
  238.         ShowString(x1+3,y1+3,str,&rlf1_s);
  239.         char sxt[128];
  240.         GetChar(MI->RF,sxt);
  241.         CreateZone(x1,y1,IconLx,IconLy,&HPSEL,MI->ID,sxt);
  242.         xx++;
  243.         if((!OBJ->Ready)&&OBJ->NUstages){
  244.             HL=div(OBJ->Ustage*(IconLx-4),OBJ->NUstages).quot;
  245.             Hline(x1+1,y1+IconLy-8,x1+HL,clrGreen);
  246.             Hline(x1+1,y1+IconLy-7,x1+HL,clrGreen);
  247.         };
  248.         if(xx>=PrpNx){
  249.             xx=0;
  250.             x1=PrpX;
  251.             y1+=IconLy;
  252.         }else x1+=IconLx;
  253.     };
  254.     //show properties of the one kind of monsters
  255.     if(NINF==1){
  256.         MI=&(MList[0]);
  257.         OBJ=Group[MI->Last];
  258.         if(!OBJ)return;
  259.         if(OBJ->Ready){
  260.             x1=PrpX+4;
  261.             y1=PrpY+IconLy+4;
  262.             sprintf(str,"╞Φτφⁿ:%d/%d",int(MI->Life),int(MI->MaxLife));
  263.             ShowString(x1,y1,str,&f16x16w);
  264.             y1+=16;
  265.             sprintf(str,"┴≡εφ :%d",int(OBJ->Ref.Visual->info.Basic.MaxShield));
  266.             ShowString(x1,y1,str,&f16x16w);
  267.             y1+=16;
  268.             sprintf(str,"╙Σα≡:%d-%d",(int(OBJ->Ref.Visual->info.Basic.MinDamage)*OBJ->xForce)>>4,(int(OBJ->Ref.Visual->info.Basic.MinDamage+OBJ->Ref.Visual->info.Basic.MaxDamage)*OBJ->xForce)>>4);
  269.             ShowString(x1,y1,str,&f16x16w);
  270.             y1+=16;
  271.             if(MI->Magic){
  272.                 sprintf(str,"╠απΦ :%d",MI->Magic);
  273.                 ShowString(x1,y1,str,&f16x16w);
  274.                 y1+=16;
  275.             };
  276.             if(OBJ->Ref.General->canNucAttack){
  277.                 sprintf(str,"╨αΩσ≥α:%d%%",div(5000-OBJ->delay,50).quot);
  278.                 ShowString(x1,y1,str,&f16x16w);
  279.                 y1+=16;
  280.             };
  281.             if(OBJ->AntiNuc){
  282.                 sprintf(str,"╨αΩσ≥:%d",OBJ->RAmount);
  283.                 ShowString(x1,y1,str,&f16x16w);
  284.                 y1+=16;
  285.                 if(OBJ->RAmount<10){
  286.                     sprintf(str,"╤δσΣ≤■∙α :%d%%",div(3000-OBJ->delay,30).quot);
  287.                     ShowString(x1,y1,str,&f16x16w);
  288.                     y1+=16;
  289.                 };
  290.             };
  291.             if(OBJ->Ref.General->cpbFarm){
  292.                 Nation* NT=OBJ->Nat;
  293.                 City* CT=NT->CITY;
  294.                 sprintf(str,"┬±σπε ⌠σ≡∞:%d",CT->ReadyAmount[OBJ->NIndex]);
  295.                 ShowString(x1,y1,str,&f16x16w);
  296.                 y1+=16;
  297.                 sprintf(str,"═≤µφε:%d",div(NT->NGidot,15).quot+1);
  298.                 ShowString(x1,y1,str,&f16x16w);
  299.                 y1+=16;
  300.                 sprintf(str,"╬ßΦ≥α≥σδσΘ:%d",NT->NGidot);
  301.                 ShowString(x1,y1,str,&f16x16w);
  302.                 y1+=16;
  303.  
  304.             };
  305.             if(OBJ->NInside){
  306.                 sprintf(str,"┬φ≤≥≡Φ:%d",OBJ->NInside);
  307.                 ShowString(x1,y1,str,&f16x16w);
  308.                 y1+=16;
  309.             };
  310.             if(OBJ->Repair){
  311.                 ShowString(x1,y1,"╨σ∞εφ≥φΦΩ",&f16x16w);
  312.                 y1+=16;
  313.             };
  314.         };
  315.     };
  316. };
  317. extern bool BuildMode;
  318. extern OneSlide* OSB;
  319. extern byte blx;
  320. extern byte bly;
  321. extern word BuildingID;
  322. extern Nation* BNat;
  323. void CmdUnProduceObj(byte NI,word Type);
  324. void RHPR(int i){
  325.     AblInf* AI=&AList[i];
  326.     Nation* NT=AI->NT;
  327.     word j=AI->OInd;
  328.     GeneralObject* GO=NT->Mon[j];
  329.     if(!GO->cpbBuilding)
  330.         CmdUnProduceObj(MyNation,j);
  331. };
  332. void HPR(int i){
  333.     AblInf* AI=&AList[i];
  334.     Nation* NT=AI->NT;
  335.     word j=AI->OInd;
  336.     GeneralObject* GO=NT->Mon[j];
  337.     if(GO->cpbBuilding){
  338.         for(int jj=0;jj<4;jj++){
  339.             byte RID=GO->ResourceID[jj];
  340.             if(RID!=255){
  341.                 if(GO->ResAmount[jj]>RESRC[MyNation][RID]){
  342.                     if(RID==1)AssignHint1("═σ ⌡Γα≥ασ≥ τεδε≥α.",20);
  343.                     if(RID==2)AssignHint1("═σ ⌡Γα≥ασ≥ Σσ≡σΓα.",20);
  344.                     return;
  345.                 };
  346.             };
  347.         };
  348.         BuildMode=true;
  349.         blx=GO->SizeX;
  350.         bly=GO->SizeY;
  351.         BuildingID=j;
  352.         BNat=NT;
  353.         word p=GO->NAnm;
  354.         for(word q=0;q<p;q++){
  355.             if(GO->lpFAnim[q].WhatFor==0)break;
  356.         };
  357.         if(q>=p)q=p-1;
  358.         OSB=GO->lpFAnim[q].Anm->Movie;
  359.     }else{
  360.         if(GetKeyState(VK_SHIFT)&0x8000){
  361.             CmdProduceObj(MyNation,j);
  362.             CmdProduceObj(MyNation,j);
  363.             CmdProduceObj(MyNation,j);
  364.             CmdProduceObj(MyNation,j);
  365.             CmdProduceObj(MyNation,j);
  366.         }else CmdProduceObj(MyNation,j);
  367.     };
  368. };
  369. void HPR1(int i){
  370.     Nation* NT=&NATIONS[MyNation];
  371.     GeneralObject* GO=NT->Mon[i];
  372.     if(GO->cpbBuilding){
  373.         for(int jj=0;jj<4;jj++){
  374.             byte RID=GO->ResourceID[jj];
  375.             if(RID!=255){
  376.                 if(GO->ResAmount[jj]>RESRC[MyNation][RID]){
  377.                     if(RID==1)AssignHint1("═σ ⌡Γα≥ασ≥ τεδε≥α.",20);
  378.                     if(RID==2)AssignHint1("═σ ⌡Γα≥ασ≥ Σσ≡σΓα.",20);
  379.                     return;
  380.                 };
  381.             };
  382.         };
  383.         BuildMode=true;
  384.         blx=GO->SizeX;
  385.         bly=GO->SizeY;
  386.         BuildingID=i;
  387.         BNat=NT;
  388.         word p=GO->NAnm;
  389.         for(word q=0;q<p;q++){
  390.             if(GO->lpFAnim[q].WhatFor==0)break;
  391.         };
  392.         if(q>=p)q=p-1;
  393.         OSB=GO->lpFAnim[q].Anm->Movie;
  394.     }else{
  395.         if(GetKeyState(VK_SHIFT)&0x8000){
  396.             CmdProduceObj(MyNation,i);
  397.             CmdProduceObj(MyNation,i);
  398.             CmdProduceObj(MyNation,i);
  399.             CmdProduceObj(MyNation,i);
  400.             CmdProduceObj(MyNation,i);
  401.         }else CmdProduceObj(MyNation,i);
  402.     }
  403. };
  404. void DoUPG(int i){
  405.     AblInf* AI=&AList[i];
  406.     Nation* NT=AI->NT;
  407.     word j=AI->OInd;
  408.     CmdPerformUpgrade(MyNation,j);
  409. };
  410. void DoUPG1(int i){
  411.     CmdPerformUpgrade(MyNation,i);
  412. };
  413. void EnterIn(int i){
  414.     if(i==0xFFFF)SubIcon=-1;
  415.     WIcon* IC=NATIONS[MyNation].wIcons[i];
  416.     if(!IC->SubList){
  417.         SubIcon=-1;
  418.         return;
  419.     };
  420.     SubIcon=i;
  421. };
  422. void OrderMove(int i,int x,int y){
  423.     CmdSendToXY(MyNation,x,y);
  424. };
  425. void OrderAttack(int i,int x,int y){
  426.     word MID=GetOwner((x<<5)+16,(y<<5)+16);
  427.     if(MID!=0xFFFF){
  428.         OneObject* OB=Group[MID];
  429.         byte Msk=1<<MyNation;
  430.         if(OB->NMask&Msk)CmdAttackToXY(MyNation,x,y);
  431.         else CmdAttackObj(MyNation,MID);
  432.     }else CmdAttackToXY(MyNation,x,y);
  433. };
  434. void OrderPatrol(int i,int x,int y){
  435.     CmdPatrol(MyNation,x,y);
  436. };
  437. void CmdSetRprState(byte NI,byte State);
  438. void OrderRepair(int i,int x,int y){
  439.     CmdSetRprState(MyNation,1);
  440. };
  441. void OrderNucAtt(int i,int x,int y){
  442.     CmdNucAtt(MyNation,x,y);
  443. };
  444. void OrderSetDst(int i,int x,int y){
  445.     CmdSetDst(MyNation,x,y);
  446. };
  447. void OrderGetResource(int i,int x,int y){
  448.     byte xx=x;
  449.     byte yy=y;
  450.     bool gl=FindResource(&xx,&yy,32,1,TZones[yy][xx]);
  451.     int xg=xx;
  452.     int yg=yy;
  453.     xx=x;
  454.     yy=y;
  455.     bool wd=FindResource(&xx,&yy,32,2,TZones[yy][xx]);
  456.     int xw=xx;
  457.     int yw=yy;
  458.     byte res=0;
  459.     if(gl&&wd){
  460.         if(abs(xg-x)+abs(yg-y)>abs(xw-x)+abs(yw-y)){
  461.             res=2;
  462.         }else res=1;
  463.     };
  464.     if(gl&&!wd)res=1;
  465.     if((!gl)&&wd)res=2;
  466.     if(res)CmdTakeRes(MyNation,x,y,res);
  467. };
  468. void OrderUnload(int i,int x,int y){
  469.     CmdUnload(MyNation,x,y);
  470. };
  471. void OrderAttPt(int i,int x,int y){
  472.     if(Links[y][x]==0xFFFF)
  473.     CmdContinueAttackPoint(MyNation,x,y);
  474.     else CmdContinueAttackWall(MyNation,x,y);
  475. };
  476. word MaxMagic;
  477. void UNIPARAM(int i){
  478.     curptr=2;
  479.     curdx=16;
  480.     curdy=15;
  481.     GetCoord=true;
  482.     UNIM=NULL;
  483.     switch(i){
  484.     case 1://Move to xy
  485.         UNIM=&OrderMove;
  486.         break;
  487.     case 2://Attack near (x,y)
  488.         UNIM=&OrderAttack;
  489.         break;
  490.     case 5://Patrol
  491.         UNIM=&OrderPatrol;
  492.         break;
  493.     case 6://Repair
  494.         UNIM=&OrderRepair;
  495.         break;
  496.     case 7:
  497.         UNIM=&OrderGetResource;
  498.         break;
  499.     case 8:
  500.         UNIM=&OrderUnload;
  501.         break;
  502.     case 9:
  503.         UNIM=&OrderAttPt;
  504.         break;
  505.     case 10:
  506.         UNIM=&OrderNucAtt;
  507.         break;
  508.     case 11:
  509.         UNIM=&OrderSetDst;
  510.         break;
  511.     };
  512. };
  513. void NOPARAM(int i){
  514.     UNIM=NULL;
  515.     switch(i){
  516.     case 3://Stop
  517.         CmdStop(MyNation);
  518.         break;
  519.     case 4://Stand Ground
  520.         CmdStandGround(MyNation);
  521.         break;
  522.     case 5:
  523.         CmdSetRprState(MyNation,1);
  524.         break;
  525.     case 6:
  526.         CmdSetRprState(MyNation,0);
  527.         break;
  528.     case 7://Build wall
  529.         SetBuildWallMode();
  530.         break;
  531.     };
  532. };
  533. void OrderPointN(int i,int x,int y){
  534.     word MID=GetOwner((x<<5)+16,(y<<5)+16);
  535.     if(MID!=0xFFFF){
  536.         OneObject* OB=Group[MID];
  537.         if(OB->NNUM!=MyNation)CmdComplexAttack(MyNation,MID,i);
  538.         else CmdComplexAttackPoint(MyNation,x,y,i);
  539.     }else 
  540.       CmdComplexAttackPoint(MyNation,x,y,i);
  541. };
  542. void OrderPoint0(int i,int x,int y){
  543.     OrderPointN(0,x,y);
  544. };
  545. void OrderPoint1(int i,int x,int y){
  546.     OrderPointN(1,x,y);
  547. };
  548. void OrderPoint2(int i,int x,int y){
  549.     OrderPointN(2,x,y);
  550. };
  551. void OrderPoint3(int i,int x,int y){
  552.     OrderPointN(3,x,y);
  553. };
  554. void OrderPoint4(int i,int x,int y){
  555.     OrderPointN(4,x,y);
  556. };
  557. void OrderPoint5(int i,int x,int y){
  558.     OrderPointN(5,x,y);
  559. };
  560. void OrderPoint6(int i,int x,int y){
  561.     OrderPointN(6,x,y);
  562. };
  563. void OrderPoint7(int i,int x,int y){
  564.     OrderPointN(7,x,y);
  565. };
  566. void OrderPoint8(int i,int x,int y){
  567.     OrderPointN(8,x,y);
  568. };
  569. void OrderPoint9(int i,int x,int y){
  570.     OrderPointN(9,x,y);
  571. };
  572. void OrderPoint10(int i,int x,int y){
  573.     OrderPointN(10,x,y);
  574. };
  575. void OrderPoint11(int i,int x,int y){
  576.     OrderPointN(11,x,y);
  577. };
  578. void STRANGEWEAPON(int i){
  579.     if(MaxMagic<NATIONS[MyNation].WMagic[i])return;
  580.     curptr=3;
  581.     curdx=16;
  582.     curdy=16;
  583.     GetCoord=true;
  584.     UNIM=NULL;
  585.  
  586.     switch(i){
  587.     case 0:
  588.         UNIM=&OrderPoint0;
  589.         break;
  590.     case 1:
  591.         UNIM=&OrderPoint1;
  592.         break;
  593.     case 2:
  594.         UNIM=&OrderPoint2;
  595.         break;
  596.     case 3:
  597.         UNIM=&OrderPoint3;
  598.         break;
  599.     case 4:
  600.         UNIM=&OrderPoint4;
  601.         break;
  602.     case 5:
  603.         UNIM=&OrderPoint5;
  604.         break;
  605.     case 6:
  606.         UNIM=&OrderPoint6;
  607.         break;
  608.     case 7:
  609.         UNIM=&OrderPoint7;
  610.         break;
  611.     case 9:
  612.         UNIM=&OrderPoint9;
  613.         break;
  614.     case 10:
  615.         UNIM=&OrderPoint10;
  616.         break;
  617.     };
  618. };
  619. int ShowUniqAbility(){
  620.     char sxt[128];
  621.     if(MList[0].Last>8192)return false;
  622.     GeneralObject* GO=MList[0].RF;
  623.     OneObject* OB=Group[MList[0].Last];
  624.     Nation* NT=OB->Nat;
  625.     if(NT!=LastNT||MList[0].Last!=LastID||GO!=LastGO)SubIcon=-1;
  626.     LastNT=NT;
  627.     LastID=MList[0].Last;
  628.     MaxMagic=MList[0].MaxMag;
  629.     LastGO=GO;
  630.     int NABL;
  631.     WIcon* SIC;
  632.     if(SubIcon==-1)NABL=GO->NIcons;
  633.     else{
  634.         SIC=NT->wIcons[SubIcon];
  635.         NABL=SIC->Param1;
  636.         if(!SIC->SubList){
  637.             SubIcon=-1;
  638.             NABL=GO->NIcons;
  639.         };
  640.     };
  641.     if(!NABL)return 0;
  642.     int AN=AblNx*AblNy;
  643.     if(NABL>AN)NABL=AN;
  644.     int xx=0;
  645.     int x1=AblX;
  646.     int y1=AblY;
  647.     OneSlide* OC;
  648.     WIcon* MI;
  649.     int IREF;
  650.     char str[32];
  651.     int p,q,spr,fid;
  652.     Visuals* VS;
  653.     for(int i=0;i<NABL;i++){
  654.         bool DrawIt=true;
  655.         if(SubIcon==-1){
  656.             MI=NT->wIcons[GO->IRefs[i]];
  657.             IREF=GO->IRefs[i];
  658.         }else{
  659.             MI=NT->wIcons[SIC->SubList[i]];
  660.             IREF=SIC->SubList[i];
  661.         };
  662.         switch(MI->Kind){
  663.         case 0:
  664.             //directory entry
  665.             ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,0);
  666.             Xbar(x1,y1,IconLx-2,IconLy-2,0x1B);
  667.             CreateZone(x1,y1,IconLx,IconLy,&EnterIn,IREF,MI->Message);
  668.             break;
  669.         case 1://uniq without param
  670.             ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,MyNation);
  671.             Xbar(x1,y1,IconLx-2,IconLy-2,0x1B);
  672.             CreateZone(x1,y1,IconLx,IconLy,&NOPARAM,MI->Param2,MI->Message);
  673.             break;
  674.         case 2://uniq with param
  675.             ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,MyNation);
  676.             Xbar(x1,y1,IconLx-2,IconLy-2,0x1B);
  677.             CreateZone(x1,y1,IconLx,IconLy,&UNIPARAM,MI->Param2,MI->Message);
  678.             break;
  679.         case 3://perform upgrade
  680.             {
  681.                 SimpleUTP* SU=NT->UPG.utp[MI->Param2];
  682.                 if(SU->Enabled){
  683.                     ShowRLCItem(x1,y1,&MImage[SU->IFileID],SU->IFIndex,MyNation);
  684.                     Xbar(x1,y1,IconLx-2,IconLy-2,240);
  685.                     Xbar(x1+1,y1+1,IconLx-3,IconLy-3,240);
  686.                     /*if(SU->Stage){
  687.                         int HL=div(int(SU->Stage)*(IconLx-4),SU->Time).quot;
  688.                         Hline(x1+1,y1+IconLy-6,x1+IconLx-4,240);
  689.                         Hline(x1+1,y1+IconLy-5,x1+HL,240);
  690.                         Hline(x1+1,y1+IconLy-4,x1+HL,240);
  691.                     };*/
  692.                     strcpy(sxt,SU->Message);
  693.                     strcat(sxt,"(");
  694.                     NT->GetUpgradeCostString(sxt,MI->Param2);
  695.                     strcat(sxt,")");
  696.                     CreateZone(x1,y1,IconLx,IconLy,&DoUPG1,MI->Param2,sxt);
  697.                 }else DrawIt=false;
  698.             };
  699.             break;
  700.         case 4://produce object
  701.             GO=NT->Mon[MI->Param2];
  702.             if(GO->Enabled){
  703.                 if(!MI->FileID){
  704.                     p=GO->NAnm;
  705.                     for(q=0;q<p;q++){
  706.                         if(GO->lpFAnim[q].WhatFor==8)break;
  707.                     };
  708.                     if(q>=p)q=p-1;
  709.                     OC=GO->lpFAnim[q].Anm->Movie;
  710.                     fid=OC->FileID;
  711.                     spr=OC->spr;
  712.                 }else{
  713.                     fid=MI->FileID;
  714.                     spr=MI->Spr;
  715.                 };
  716.                 ShowRLCItem(x1,y1,&MImage[fid],spr,MyNation);
  717.                 Xbar(x1,y1,IconLx-2,IconLy-2,15);
  718.                 //int GA=GetAmount(MI->OInd);
  719.                 //int GP=GetProgress(MI->OInd);
  720.                 //if(GA!=0){
  721.                 //    sprintf(str,"%d",GA);
  722.                 //    ShowString(x1+2,y1+2,str,&rlf1_s);
  723.                 //};
  724.                 //int HL=div(GP*(IconLx-4),200).quot;
  725.                 //Hline(x1+1,y1+IconLy-6,x1+IconLx-4,15);
  726.                 //Hline(x1+1,y1+IconLy-5,x1+HL,255);
  727.                 //Hline(x1+1,y1+IconLy-4,x1+HL,255);
  728.                 VS=(Visuals*)GO;
  729.                 GetChar(GO,sxt);
  730.                 GO->GetMonsterCostString(sxt);
  731.                 CreateZone(x1,y1,IconLx,IconLy,&HPR1,MI->Param2,sxt);
  732.             }else DrawIt=false;
  733.             break;
  734.         case 5://strange weapon
  735.             if(NT->SWP[MI->Param1].Enabled){
  736.                 ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,MyNation);
  737.                 CreateZone(x1,y1,IconLx,IconLy,&STRANGEWEAPON,MI->Param2,MI->Message);
  738.             }else DrawIt=false;
  739.             break;
  740.         };
  741.         if(DrawIt){
  742.             xx++;
  743.             if(xx>=AblNx){
  744.                 xx=0;
  745.                 x1=PrpX;
  746.                 y1+=IconLy;
  747.             }else x1+=IconLx;
  748.         };
  749.     };
  750.     if(GO->ExtMenu)return NABL;
  751.     return -1;
  752. };
  753. bool ShowCommonAbl(){
  754.     bool isAir=false;
  755.     bool isWater=false;
  756.     bool isLand=false;
  757.     for(int i=0;i<NINF;i++){
  758.         GeneralObject* GO=MList[i].RF;
  759.         if(GO->Kind==2&&!(GO->OnAir||GO->OnWater))isLand=true;
  760.         if(GO->Kind==2&&GO->OnWater)isWater=true;
  761.         if(GO->Kind==5)isAir=true;
  762.     };
  763.     char sxt[128];
  764.     if(!(isAir||isLand||isWater))return false;
  765.     Nation* NT=&NATIONS[MyNation];
  766.     word NIcons;
  767.     word* Icons=NULL;
  768.     if(isAir&&!(isLand||isWater)){
  769.         NIcons=NT->NAmenus;
  770.         Icons=NT->Amenus;
  771.     };
  772.     if(isLand&&!(isAir||isWater)){
  773.         NIcons=NT->NLmenus;
  774.         Icons=NT->Lmenus;
  775.     };
  776.     if(isWater&&!(isAir||isLand)){
  777.         NIcons=NT->NWmenus;
  778.         Icons=NT->Wmenus;
  779.     };
  780.     if(!Icons){
  781.         NIcons=NT->NCmenus;
  782.         Icons=NT->Cmenus;
  783.     };
  784.     
  785.     if(NT!=LastNT||LastID!=7777)SubIcon=-1;
  786.     LastID=7777;
  787.     LastNT=NT;
  788.     int NABL;
  789.     WIcon* SIC;
  790.     if(SubIcon==-1)NABL=NIcons;
  791.     else{
  792.         SIC=NT->wIcons[SubIcon];
  793.         NABL=SIC->Param1;
  794.         if(!SIC->SubList){
  795.             SubIcon=-1;
  796.             NABL=NIcons;
  797.         };
  798.     };
  799.     int AN=AblNx*AblNy;
  800.     if(NABL>AN)NABL=AN;
  801.     int xx=0;
  802.     int x1=AblX;
  803.     int y1=AblY;
  804.     OneSlide* OC;
  805.     WIcon* MI;
  806.     int IREF;
  807.     char str[32];
  808.     int p,q,spr,fid;
  809.     Visuals* VS;
  810.     MaxMagic=0;
  811.     for(i=0;i<NABL;i++){
  812.         if(SubIcon==-1){
  813.             MI=NT->wIcons[Icons[i]];
  814.             IREF=Icons[i];
  815.         }else{
  816.             MI=NT->wIcons[SIC->SubList[i]];
  817.             IREF=SIC->SubList[i];
  818.         };
  819.         switch(MI->Kind){
  820.         case 0:
  821.             //directory entry
  822.             ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,0);
  823.             Xbar(x1,y1,IconLx-2,IconLy-2,0x1B);
  824.             CreateZone(x1,y1,IconLx,IconLy,&EnterIn,IREF,MI->Message);
  825.             break;
  826.         case 1://uniq without param
  827.             ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,MyNation);
  828.             Xbar(x1,y1,IconLx-2,IconLy-2,0x1B);
  829.             CreateZone(x1,y1,IconLx,IconLy,&NOPARAM,IREF,MI->Message);
  830.             break;
  831.         case 2://uniq with param
  832.             ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,MyNation);
  833.             Xbar(x1,y1,IconLx-2,IconLy-2,0x1B);
  834.             CreateZone(x1,y1,IconLx,IconLy,&UNIPARAM,MI->Param2,MI->Message);
  835.             break;
  836.         case 3://perform upgrade
  837.             /*{
  838.                 SimpleUTP* SU=NT->UPG.utp[MI->Param2];
  839.                 ShowRLCItem(x1,y1,&MImage[SU->IFileID],SU->IFIndex,0);
  840.                 Xbar(x1,y1,IconLx-2,IconLy-2,240);
  841.                 Xbar(x1+1,y1+1,IconLx-3,IconLy-3,240);
  842.                 strcpy(sxt,SU->Message);
  843.                 strcat(sxt,"(");
  844.                 NT->GetUpgradeCostString(sxt,MI->Param2);
  845.                 strcat(sxt,")");
  846.                 CreateZone(x1,y1,IconLx,IconLy,&DoUPG1,MI->Param2,sxt);
  847.             };*/
  848.             break;
  849.         case 4://produce object
  850.             /*GO=NT->Mon[MI->Param2];
  851.             if(!MI->FileID){
  852.                 p=GO->NAnm;
  853.                 for(q=0;q<p;q++){
  854.                     if(GO->lpFAnim[q].WhatFor==8)break;
  855.                 };
  856.                 if(q>=p)q=p-1;
  857.                 OC=GO->lpFAnim[q].Anm->Movie;
  858.                 fid=OC->FileID;
  859.                 spr=OC->spr;
  860.             }else{
  861.                 fid=MI->FileID;
  862.                 spr=MI->Spr;
  863.             };
  864.             ShowRLCItem(x1,y1,&MImage[fid],spr,0);
  865.             Xbar(x1,y1,IconLx-2,IconLy-2,15);
  866.             //int GA=GetAmount(MI->OInd);
  867.             //int GP=GetProgress(MI->OInd);
  868.             //if(GA!=0){
  869.             //    sprintf(str,"%d",GA);
  870.             //    ShowString(x1+2,y1+2,str,&rlf1_s);
  871.             //};
  872.             //int HL=div(GP*(IconLx-4),200).quot;
  873.             //Hline(x1+1,y1+IconLy-6,x1+IconLx-4,15);
  874.             //Hline(x1+1,y1+IconLy-5,x1+HL,255);
  875.             //Hline(x1+1,y1+IconLy-4,x1+HL,255);
  876.             VS=(Visuals*)GO;
  877.             GetChar(GO,sxt);
  878.             GO->GetMonsterCostString(sxt);
  879.             CreateZone(x1,y1,IconLx,IconLy,&HPR1,MI->Param2,sxt);
  880.             */
  881.             break;
  882.         case 5://strange weapon
  883.             ShowRLCItem(x1,y1,&MImage[MI->FileID],MI->Spr,MyNation);
  884.             Xbar(x1,y1,IconLx-2,IconLy-2,0x1C);
  885.             CreateZone(x1,y1,IconLx,IconLy,&STRANGEWEAPON,MI->Param2,MI->Message);
  886.             break;
  887.         };
  888.         xx++;
  889.         if(xx>=AblNx){
  890.             xx=0;
  891.             x1=PrpX;
  892.             y1+=IconLy;
  893.         }else x1+=IconLx;
  894.     };
  895.     return true;
  896.  
  897. };
  898. void ShowAbility(){
  899.     char sxt[128];
  900.     //InitZones();
  901.     NABL=0;
  902.     word MID;
  903.     OneObject* OBJ;
  904.     GeneralObject* GO;
  905.     AblInf* MI;
  906.     Nation* NT;
  907.     word s;
  908.     int i,j,k,p,q,r;
  909.     //if(NINF)ResFon(AblX,AblY,AblNx*IconLx,AblNy*IconLy);
  910.     if(!NINF){
  911.         //ResFon(AblX,AblY,AblNx*IconLx,AblNy*IconLy);
  912.         //ScrCopy(PrpX,PrpY,PrpNx*IconLx,PrpNy*IconLy);
  913.         return;
  914.     };
  915.     int nability=0;
  916.     if(NINF==1){
  917.         nability=ShowUniqAbility();
  918.         if(nability==-1)return;
  919.     };
  920.     if(ShowCommonAbl())return;
  921.     //calculating monsters could be produced
  922.     for(i=0;i<NINF;i++){
  923.         OBJ=Group[MList[i].Last];
  924.         if(OBJ->Ready){
  925.             NT=OBJ->Nat;
  926.             k=OBJ->Index;
  927.             p=OBJ->NIndex;
  928.             q=NT->PACount[p];
  929.             for(r=0;r<q;r++){
  930.                 s=NT->PAble[p][r];    
  931.                 if(NT->Mon[s]->Enabled){
  932.                     for(j=0;j<NABL;j++){
  933.                         if(AList[j].OInd==s)break;
  934.                     };
  935.                     AList[j].OInd=s;
  936.                     AList[j].NT=NT;
  937.                     AList[j].Kind=0;
  938.                     if(j>=NABL)NABL=j+1;
  939.                 };
  940.             };
  941.         };
  942.     };
  943.     //calculate upgrades
  944.     for(i=0;i<NINF;i++){
  945.         OBJ=Group[MList[i].Last];
  946.         if(OBJ->Ready){
  947.             NT=OBJ->Nat;
  948.             k=OBJ->Index;
  949.             p=OBJ->NIndex;
  950.             GeneralObject* GO=NT->Mon[p];
  951.             q=GO->NUpgrades;
  952.             for(r=0;r<q;r++){
  953.                 s=GO->Upg[r];    
  954.                 if(NT->UPG.utp[s]->Enabled){
  955.                     for(j=0;j<NABL;j++){
  956.                         if(AList[j].Kind==1&&AList[j].OInd==s)break;
  957.                     };
  958.                     AList[j].OInd=s;
  959.                     AList[j].NT=NT;
  960.                     AList[j].Kind=1;
  961.                     if(j>=NABL)NABL=j+1;
  962.                 };
  963.             };
  964.         };
  965.     };
  966.     //show abilities
  967.     int AN=AblNx*AblNy;
  968.     if(NABL>AN)NABL=AN;
  969.     int xx=nability;
  970.     int x1=AblX+IconLx*(xx&3);
  971.     int y1=AblY+IconLy*(xx>>2);
  972.     xx=xx&3;
  973.     OneSlide* OC;
  974.     char str[32];
  975.     for(i=0;i<NABL;i++){
  976.         MI=&(AList[i]);
  977.         switch(MI->Kind){
  978.         case 0:{
  979.             GO=(MI->NT)->Mon[MI->OInd];
  980.             p=GO->NAnm;
  981.                 for(q=0;q<p;q++){
  982.                 if(GO->lpFAnim[q].WhatFor==8)break;
  983.             };
  984.             if(q>=p)q=p-1;
  985.             OC=GO->lpFAnim[q].Anm->Movie;
  986.             ShowRLCItem(x1,y1,&MImage[OC->FileID],OC->spr,MyNation);
  987.             Xbar(x1,y1,IconLx-2,IconLy-2,15);
  988.             int GA=GetAmount(MI->OInd);
  989.             int GP=GetProgress(MI->OInd);
  990.             if(GA!=0){
  991.                 sprintf(str,"%d",GA);
  992.                 ShowString(x1+2,y1+2,str,&rlf1_s);
  993.             };
  994.             int HL=div(GP*(IconLx-4),GO->NStages<<1).quot;
  995.             Hline(x1+1,y1+IconLy-6,x1+IconLx-4,15);
  996.             Hline(x1+1,y1+IconLy-5,x1+HL,255);
  997.             Hline(x1+1,y1+IconLy-4,x1+HL,255);
  998.             Visuals* VS=(Visuals*)GO;
  999.             GetChar(GO,sxt);
  1000.             GO->GetMonsterCostString(sxt);
  1001.             CreateRZone(x1,y1,IconLx,IconLy,&HPR,&RHPR,i,sxt);};
  1002.             break;
  1003.         case 1://upgrade caps
  1004.             {
  1005.                 SimpleUTP* SU=MI->NT->UPG.utp[MI->OInd];
  1006.                 ShowRLCItem(x1,y1,&MImage[SU->IFileID],SU->IFIndex,MyNation);
  1007.                 Xbar(x1,y1,IconLx-2,IconLy-2,240);
  1008.                 Xbar(x1+1,y1+1,IconLx-3,IconLy-3,240);
  1009.                 if(SU->Stage){
  1010.                     int HL=div(int(SU->Stage)*(IconLx-4),SU->Time).quot;
  1011.                     Hline(x1+1,y1+IconLy-6,x1+IconLx-4,240);
  1012.                     Hline(x1+1,y1+IconLy-5,x1+HL,240);
  1013.                     Hline(x1+1,y1+IconLy-4,x1+HL,240);
  1014.                 };
  1015.                 strcpy(sxt,SU->Message);
  1016.                 strcat(sxt,"(");
  1017.                 MI->NT->GetUpgradeCostString(sxt,MI->OInd);
  1018.                 strcat(sxt,")");
  1019.                 CreateZone(x1,y1,IconLx,IconLy,&DoUPG,i,sxt);
  1020.             };
  1021.             break;
  1022.         };
  1023.         xx++;
  1024.         if(xx>=AblNx){
  1025.             xx=0;
  1026.             x1=PrpX;
  1027.             y1+=IconLy;
  1028.         }else x1+=IconLx;
  1029.     };
  1030. };
  1031. void PropCopy(){
  1032.     int AY=NABL>>2;
  1033.     if(NABL&3)AY++;
  1034.     int PY=NINF>>2;
  1035.     if(NINF&3)PY++;
  1036.     if(AY>8)AY=0;
  1037.     if(PY>8)PY=0;
  1038.     AY=4;
  1039.     PY=2;
  1040.     if(PY)ScrCopy(PrpX,PrpY,PrpNx*IconLx,PY*IconLy);
  1041.     if(AY)ScrCopy(AblX,AblY,AblNx*IconLx,AY*IconLy);
  1042. };
  1043.