home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / conquer3 / patch3 / trade.c < prev   
C/C++ Source or Header  |  1988-07-19  |  25KB  |  917 lines

  1. /*conquer : Copyright (c) 1988 by Ed Barlow.
  2.  *  I spent a long time writing this code & I hope that you respect this.  
  3.  *  I give permission to alter the code, but not to copy or redistribute
  4.  *  it without my explicit permission.  If you alter the code, 
  5.  *  please document changes and send me a copy, so all can have it.  
  6.  *  This code, to the best of my knowledge works well,  but it is my first
  7.  *  'C' program and should be treated as such.  I disclaim any
  8.  *  responsibility for the codes actions (use at your own risk).  I guess
  9.  *  I am saying "Happy gaming", and am trying not to get sued in the process.
  10.  *                                                Ed
  11.  */
  12.  
  13. /*
  14.  *  The following file "trade.c" was written by Adam Bryant who
  15.  *  gives all rights to this code to Ed Barlow provided that this
  16.  *  message remains intact.
  17.  */
  18.  
  19. /* thanks adam -- Ed */
  20.  
  21. /*    trade.c        */
  22.  
  23. /*include files*/
  24. #include "header.h"
  25. #include "data.h"
  26.  
  27. #ifdef TRADE        
  28.  
  29. /* possible commodities */
  30. #define TDGOLD   0
  31. #define TDFOOD   1
  32. #define TDIRON   2
  33. #define TDJEWL   3
  34. #define TDLAND   4
  35. #define TDARMY   5
  36. #define TDSHIP   6
  37.  
  38. /* constants and indicators */
  39. #define    NUMPRODUCTS    7
  40. #define    MAXITM    30
  41. #define    SELL    0
  42. #define    BUY    1
  43. #define    NODEAL    2
  44. #define    NOSALE    3
  45. #define TRADECOST(cost)    ((100-cost)/100)    /* twenty percent cost normal*/
  46.  
  47. extern short country;
  48.  
  49. char *commodities[NUMPRODUCTS] = { "Gold", "Food", "Iron", "Jewels",
  50.         "Land", "Soldiers", "Ships"};
  51. #ifdef ADMIN
  52. char *tradefail[NUMPRODUCTS] = { "lack of gold", "lack of food",
  53.     "lack of iron", "lack of jewels", "land not owned",
  54.     "no available armies", "no available navies"};
  55. #endif ADMIN
  56. #ifdef CONQUER
  57. /* Use this when you wish to sell something */
  58. char *selllist[NUMPRODUCTS] = { "Sell how many gold talons? ", "Sell how much food? ",
  59.     "Sell how much iron? ", "Sell how many jewels? ", "What X location? ",
  60.     "How many soldiers? ", "How many ships? "};
  61.  
  62. /* Use this when you wish to place a bid something */
  63. char *buylist[NUMPRODUCTS] = { "Bid how much gold? ", "Bid how much food? ",
  64.     "Bid how much iron? ", "Bid how many jewels? ", " ",
  65.     "Bid what army? ", "Bid how many ships? "};
  66.  
  67. void
  68. trade()
  69. {
  70.     FILE *tfile;
  71.     int count, done=FALSE, notopen=FALSE;
  72.     int buysell, holdint, holdint2, extint, inloop;
  73.     int type1[MAXITM], type2[MAXITM], deal[MAXITM], extra[MAXITM];
  74.     int natn[MAXITM], itemnum, getland(), gettrade(), checkland();
  75.     int tradable();
  76.     long lvar1[MAXITM], lvar2[MAXITM], holdlong, holdlong2, armyvalue();
  77.     void tradeerr(), setaside(), takeback();
  78.     
  79.     while (done==FALSE) {
  80.         itemnum=0;
  81.         done=TRUE;
  82.         /* open trading file */
  83.         if ((tfile=fopen(tradefile,"r")) == NULL ) {
  84.             notopen=TRUE;
  85.         }
  86.         /* read in all of the data */
  87.         while (notopen==FALSE && !feof(tfile)) {
  88.             fscanf(tfile,"%d %d %d %d %ld %ld %d\n",&deal[itemnum],
  89.                 &natn[itemnum],&type1[itemnum],&type2[itemnum],&lvar1[itemnum],&lvar2[itemnum],&extra[itemnum]);
  90.             if (deal[itemnum]==NOSALE) {
  91.                 /* remove item from sales list */
  92.                 deal[type1[itemnum]]=NOSALE;
  93.             } else if (deal[itemnum]==SELL) {
  94.                 itemnum++;
  95.             }
  96.         }
  97.         if (notopen==FALSE) fclose(tfile);
  98.         clear();
  99.         /* display header */
  100.         standout();
  101.         mvaddstr(0,27,"COMMODITIES EXCHANGE");
  102.         standend();
  103.         count=2;
  104.         mvprintw(count,0,"    Nation\t\tItem\t\tMinimum Price");
  105.         /* go through list of commodities */
  106.         for (holdint=0;holdint<itemnum;holdint++) {
  107.             if (deal[holdint]==SELL) {
  108.                 count++;
  109.                 mvprintw(count,0,"%2d) %-10s",
  110.                     holdint+1,
  111.                     ntn[natn[holdint]].name);
  112.  
  113.                 if (type1[holdint]==TDLAND) {
  114.                     holdlong = (long) tofood(sct[(int)lvar1[holdint]][extra[holdint]].vegetation,0);
  115.                     mvprintw(count,20,"(food=%2ld) %s",
  116.                         holdlong,
  117.                         commodities[type1[holdint]]);
  118.                 } else {
  119.                     holdlong = lvar1[holdint];
  120.                     mvprintw(count,20,"%9ld %s",
  121.                         holdlong,
  122.                         commodities[type1[holdint]]);
  123.                 }
  124.                 mvprintw(count,40,"%9ld %s",
  125.                     lvar2[holdint],
  126.                     commodities[type2[holdint]]);
  127.                 if (count>16) {
  128.                     standout();
  129.                     mvaddstr(21,30,"Hit Any Key to Continue");
  130.                     standend();
  131.                     refresh();
  132.                     getch();
  133.                     clear();
  134.                     standout();
  135.                     mvaddstr(0,27,"COMMODITIES EXCHANGE");
  136.                     standend();
  137.                     mvprintw(2,0,"    Nation\t\tItem\t\tMinimum Price");
  138.                     count=3;
  139.                 }
  140.             }
  141.         }
  142.         standout();
  143.         count++;
  144.         if (itemnum==0)    mvaddstr(count++,0,"Nothing to Buy.  Do you wish to (S)ell?");
  145.         else mvaddstr(count++,0,"Do you wish to (B)uy, (S)ell, or (U)nsell?");
  146.         standend();
  147.         refresh();
  148.         inloop=TRUE;
  149.         while (inloop==TRUE) switch(getch()) {
  150.         case 'b':
  151.         case 'B':
  152.             if (itemnum==0) break;
  153.             buysell=BUY;
  154.             mvaddstr(count++,0,"What item number do you want to purchase? ");
  155.             refresh();
  156.             holdint = get_number();
  157.             if (holdint<1 || holdint>itemnum) {
  158.                 tradeerr("Invalid Item Number");
  159.                 return;
  160.             }
  161.             holdint--;
  162.             if (deal[holdint]!=SELL) {
  163.                 tradeerr("Sorry, that item is not on the market.");
  164.                 return;
  165.             }
  166.             if (ntn[natn[holdint]].dstatus[country]==UNMET) {
  167.                 tradeerr("That nation has not been met by you");
  168.                 return;
  169.             }
  170.             if (ntn[natn[holdint]].dstatus[country]>HOSTILE) {
  171.                 tradeerr("That nation is not doing business with you");
  172.                 return;
  173.             }
  174.             /* obtain bid */
  175.             mvprintw(count++,0,"%s",buylist[type2[holdint]]);
  176.             refresh();
  177.             holdlong2 = 0L;
  178.             holdlong = (long) get_number();
  179.             /* check for valid bid */
  180.             switch(type2[holdint]) {
  181.             case TDGOLD:
  182.                 if (holdlong < lvar2[holdint]) {
  183.                     tradeerr("You underbid the minimum.");
  184.                     buysell=NODEAL;
  185.                 } else if (holdlong > ntn[country].tgold) {
  186.                     tradeerr("Not Enough Gold");
  187.                     buysell=NODEAL;
  188.                 }
  189.                 break;
  190.             case TDFOOD:
  191.                 if (holdlong < lvar2[holdint]) {
  192.                     tradeerr("You underbid the minimum.");
  193.                     buysell=NODEAL;
  194.                 } else if (holdlong > ntn[country].tfood) {
  195.                     tradeerr("Not Enough Food");
  196.                     buysell=NODEAL;
  197.                 }
  198.                 break;
  199.             case TDIRON:
  200.                 if (holdlong < lvar2[holdint]) {
  201.                     tradeerr("You underbid the minimum.");
  202.                     buysell=NODEAL;
  203.                 } else if (holdlong > ntn[country].tiron) {
  204.                     tradeerr("Not Enough Iron");
  205.                     buysell=NODEAL;
  206.                 }
  207.                 break;
  208.             case TDJEWL:
  209.                 if (holdlong < lvar2[holdint]) {
  210.                     tradeerr("You underbid the minimum.");
  211.                     buysell=NODEAL;
  212.                 } else if (holdlong > ntn[country].jewels) {
  213.                     tradeerr("Not Enough Jewels");
  214.                     buysell=NODEAL;
  215.                 }
  216.                 break;
  217.             case TDLAND:
  218.                 mvaddstr(count++,0,"What Y position? ");
  219.                 refresh();
  220.                 holdlong2 = (long) get_number;
  221.                 if (checkland(BUY,(int)(holdlong),(int)(holdlong2))==NODEAL) {
  222.                     buysell=NODEAL;
  223.                 } else if (tofood(sct[(int)holdlong][(int)holdlong2].vegetation,natn[holdint]) < lvar2[holdint]) {
  224.                     tradeerr("You underbid the minimum");
  225.                     buysell=NODEAL;
  226.                 }
  227.                 break;
  228.             case TDARMY:
  229.                 if ((int)holdlong > MAXARM) {
  230.                     tradeerr("Invalid Unit");
  231.                     buysell=NODEAL;
  232.                 } else if (tradable(country,(int)holdlong)==FALSE) {
  233.                     tradeerr("That unit type is non-tradable.");
  234.                     buysell=NODEAL;
  235.                 } else if (armyvalue(country,(int)holdlong) < lvar2[holdint]) {
  236.                     tradeerr("You underbid the minimum.");
  237.                     buysell=NODEAL;
  238.                 }
  239.                 break;
  240.             case TDSHIP:
  241.                 if ((int)holdlong >= MAXNAVY) {
  242.                     tradeerr("Invalid Navy");
  243.                     buysell=NODEAL;
  244.                 } else if (ntn[country].nvy[(int)holdlong].merchant+ntn[country].nvy[(int)holdlong].warships < (int)lvar2[holdint]) {
  245.                     tradeerr("You underbid the minimum.");
  246.                     buysell=NODEAL;
  247.                 }
  248.                 break;
  249.             default:
  250.                 tradeerr("Invalid Commodity");
  251.                 buysell=NODEAL;
  252.                 break;
  253.             }
  254.             if (buysell==BUY) {
  255.                 if ( (tfile = fopen(tradefile,"a+"))==NULL) {
  256.                     tradeerr("Error opening file for trading");
  257.                     abrt();
  258.                 }
  259.                 setaside(country,type2[holdint],holdlong);
  260.                 fprintf(tfile, "%d %d %d %d %ld %ld %d\n",BUY, country, holdint, 0, holdlong, holdlong2, 0);
  261.                 fclose(tfile);
  262.             }
  263.             return;
  264.         case 's':
  265.         case 'S':
  266.             /* sell an item */
  267.             /* only allow MAXITM on market */
  268.             if (itemnum>=MAXITM) {
  269.                 standout();
  270.                 if (itemnum==0) mvaddstr(count++,0,"Market Congested.  Hit any key to continue");
  271.                 else mvaddstr(count++,0,"Market Congested.  (B)uy or any key to continue");
  272.                 standend();
  273.                 refresh();
  274.                 break;
  275.             }
  276.             buysell=SELL;
  277.             holdint = gettrade("Selling",&count);
  278.             if (holdint==(-1)) {
  279.                 tradeerr("Invalid Option");
  280.                 return;
  281.             }
  282.  
  283.             mvprintw(count++,0,"%s",selllist[holdint]);
  284.             refresh();
  285.             /* find out how much commodities */
  286.             holdlong = (long) get_number();
  287.             extint = 0;
  288.             if (holdint< TDLAND && holdlong==0L)
  289.                 return;
  290.  
  291.             /* check for valid items */
  292.             switch(holdint) {
  293.             case TDGOLD:
  294.                 if (holdlong > ntn[country].tgold) {
  295.                     tradeerr("Not Enough Gold");
  296.                     buysell=NODEAL;
  297.                 }
  298.                 break;
  299.             case TDFOOD:
  300.                 if (holdlong > ntn[country].tfood) {
  301.                     tradeerr("Not Enough Food");
  302.                     buysell=NODEAL;
  303.                 }
  304.                 break;
  305.             case TDIRON:
  306.                 if (holdlong > ntn[country].tiron) {
  307.                     tradeerr("Not Enough Iron");
  308.                     buysell=NODEAL;
  309.                 }
  310.                 break;
  311.             case TDJEWL:
  312.                 if (holdlong > ntn[country].jewels) {
  313.                     tradeerr("Not Enough Jewels");
  314.                     buysell=NODEAL;
  315.                 }
  316.                 break;
  317.             case TDLAND:
  318.                 mvprintw(count++,0,"What Y position? ");
  319.                 refresh();
  320.                 extint = get_number();
  321.                 buysell = checkland(SELL,(int)holdlong,extint);
  322.                 break;
  323.             case TDARMY:
  324.                 if (holdlong>=MAXARM || ntn[country].arm[(int)holdlong].sold <= 0) {
  325.                     tradeerr("Invalid Army");
  326.                     buysell=NODEAL;
  327.                 } else if (tradable(country,(int)holdlong)==FALSE) {
  328.                     tradeerr("That unit is non-tradable.");
  329.                     buysell=NODEAL;
  330.                 }
  331.                 break;
  332.             case TDSHIP:
  333.                 if (holdlong>=MAXNAVY || ntn[country].nvy[(int)holdlong].merchant + ntn[country].nvy[(int)holdlong].warships <= 0) {
  334.                     tradeerr("Invalid Navy");
  335.                     buysell=NODEAL;
  336.                 }
  337.                 break;
  338.             default:
  339.                 tradeerr("Invalid Commodity");
  340.                 buysell=NODEAL;
  341.                 break;
  342.             }
  343.             /* invalid commodity */
  344.             if (buysell==NODEAL) return;
  345.  
  346.             /* find out what they want in trade */
  347.             holdint2 = gettrade("In Trade For",&count);
  348.             if (holdint2==(-1)) {
  349.                 tradeerr("Invalid Option");
  350.                 return;
  351.             }
  352.             if (holdint2==TDLAND) {
  353.                 holdlong2 = (long) getland(&count);
  354.                 if (holdlong2==(-1L)) {
  355.                     tradeerr("Invalid Vegetation");
  356.                     return;
  357.                 }
  358.             } else {
  359.                 /* find out for what value */
  360.                 mvprintw(count++,0,"Minimum %s",selllist[holdint2]);
  361.                 refresh();
  362.                 holdlong2 = (long) get_number();
  363.                 if (holdlong2 == 0L) return;
  364.             }
  365.  
  366.             /* make sure what was bid is unusable */
  367.             setaside(country,holdint,holdlong);
  368.  
  369.             /* set up output properly */
  370.             if (holdint==TDARMY) {
  371.                 extint = (int) holdlong;
  372.                 holdlong = armyvalue(country,(int)holdlong);
  373.             }
  374.             else if (holdint==TDSHIP) {
  375.                 extint = (int)holdlong;
  376.                 holdlong = (long)(ntn[country].nvy[(int)holdlong].merchant + ntn[country].nvy[(int)holdlong].warships);
  377.             }
  378.  
  379.             /* send it out */
  380.             if ( (tfile = fopen(tradefile,"a+"))==NULL) {
  381.                 tradeerr("Error opening file for trading");
  382.                 abrt();
  383.             }
  384.             fprintf(tfile, "%d %d %d %d %ld %ld %d\n", SELL, country, holdint, holdint2, holdlong, holdlong2, extint);
  385.             fclose(tfile);
  386.             inloop=FALSE;
  387.             done=FALSE;
  388.             break;
  389.         case 'u':
  390.         case 'U':
  391.             /* unsell an item */
  392.             if (itemnum==0) break;
  393.             mvaddstr(count++,0,"What item number to remove? ");
  394.             refresh();
  395.             holdint = get_number();
  396.             if (holdint==0 || holdint>itemnum) {
  397.                 tradeerr("Invalid Item Number");
  398.                 return;
  399.             }
  400.             holdint--;
  401. #ifdef OGOD
  402.             /* allow god to remove commodities */
  403.             if (country!=0 && country!=natn[holdint]) 
  404. #else 
  405.             if (country != natn[holdint]) 
  406. #endif OGOD
  407.             {
  408.                 tradeerr("That is not your item");
  409.                 return;
  410.             }
  411.             
  412.             /* remove it from market */
  413.             if ( (tfile = fopen(tradefile,"a+"))==NULL) {
  414.                 tradeerr("Error opening file for trading");
  415.                 abrt();
  416.             }
  417.             fprintf(tfile, "%d %d %d %d %ld %ld %d\n", NOSALE, natn[holdint], holdint, 0, 0L, 0L, 0);
  418.             fclose(tfile);
  419.             takeback(natn[holdint],type1[holdint],lvar1[holdint]);
  420.             /*redraw the commodities board so removal is seen*/
  421.             inloop=FALSE;
  422.             done=FALSE;
  423.             break;
  424.         default:
  425.             /* return on no choice */
  426.             return;
  427.         }
  428.     }
  429. }
  430.  
  431. void
  432. tradeerr(mesg)
  433. char *mesg;
  434. {
  435.     clear_bottom(0);
  436.     standout();
  437.     mvaddstr(21,0,mesg);
  438.     standend();
  439.     mvaddstr(22,0,"Hit any key to continue");
  440.     refresh();
  441.     getch();
  442. }
  443.  
  444. int
  445. checkland(tradestat,xspot,yspot)
  446. int tradestat,xspot,yspot;
  447. {
  448.     int newstat=tradestat;
  449.     if (xspot < 0 || xspot > MAPX || yspot > MAPY || yspot < 0) {
  450.         tradeerr("That is off the map");
  451.         newstat=NODEAL;
  452.     } 
  453.     else if (sct[xspot][yspot].owner != country) {
  454.         tradeerr("You don't own it");
  455.         newstat=NODEAL;
  456.     }
  457.     else if (ntn[country].capx==xspot && ntn[country].capy==yspot) {
  458.         tradeerr("That is your capitol");
  459.         newstat=NODEAL;
  460.     }
  461.     else if (sct[xspot][yspot].designation == DCITY) {
  462.         tradeerr("Towns may not be sold");
  463.         newstat=NODEAL;
  464.     }
  465.     return(newstat);
  466. }
  467.  
  468. /* get minimum foodvalue for land */
  469. int
  470. getland(count)
  471. int *count;
  472. {
  473.     int    temp;
  474.     char    entered;
  475.  
  476.     mvprintw((*count)++,0,"MINIMUM VEGETATION: %c, %c, %c, %c, %c, %c, %c, %c, %c, %c, %c or %c: ",
  477.         VOLCANO,DESERT,TUNDRA,BARREN,LT_VEG,
  478.         GOOD,WOOD,FOREST,JUNGLE,SWAMP,ICE,NONE);
  479.  
  480.     refresh();
  481.     entered=getch();
  482.     if(entered!=VOLCANO       &&entered!=JUNGLE
  483.         &&entered!=DESERT &&entered!=TUNDRA
  484.         &&entered!=BARREN &&entered!=LT_VEG
  485.         &&entered!=NONE   &&entered!=GOOD
  486.         &&entered!=WOOD   &&entered!=FOREST
  487.         &&entered!=SWAMP  &&entered!=ICE) temp=(-1);
  488.     else temp = tofood(entered,country);
  489.     mvprintw((*count)++,0," JUST ENTERED %c so temp is %d", entered,temp);
  490.     return(temp);
  491. }
  492.  
  493. int
  494. gettrade(saletype,count)
  495. char *saletype;
  496. int *count;
  497. {
  498.     int hold=(-1);
  499.  
  500.     mvprintw((*count)++,0,"%s: (G)old, (F)ood, (I)ron, (J)ewels, (L)and, (A)rmy, (S)hips?",saletype);
  501.     refresh();
  502.     switch(getch()) {
  503.     case 'g':
  504.     case 'G':
  505.         hold=TDGOLD;
  506.         break;
  507.     case 'f':
  508.     case 'F':
  509.         hold=TDFOOD;
  510.         break;
  511.     case 'i':
  512.     case 'I':
  513.         hold=TDIRON;
  514.         break;
  515.     case 'j':
  516.     case 'J':
  517.         hold=TDJEWL;
  518.         break;
  519.     case 'l':
  520.     case 'L':
  521.         hold=TDLAND;
  522.         break;
  523.     case 'a':
  524.     case 'A':
  525.         hold=TDARMY;
  526.         break;
  527.     case 's':
  528.     case 'S':
  529.         hold=TDSHIP;
  530.         break;
  531.     default:
  532.         break;
  533.     }
  534.     return(hold);
  535. }
  536.  
  537. /* set aside things that are up for bid */
  538. void
  539. setaside(cntry,item,longval)
  540. int cntry,item;
  541. long longval;
  542. {
  543.     switch(item)
  544.     {
  545.     case TDGOLD:
  546.         ntn[cntry].tgold -= longval;
  547.         break;
  548.     case TDFOOD:
  549.         ntn[cntry].tfood -= longval;
  550.         break;
  551.     case TDIRON:
  552.         ntn[cntry].tiron -= longval;
  553.         break;
  554.     case TDJEWL:
  555.         ntn[cntry].jewels -= longval;
  556.         break;
  557.     case TDLAND:
  558.         break;
  559.     case TDARMY:
  560.         ntn[cntry].arm[(int)longval].smove = 0;
  561.         ntn[cntry].arm[(int)longval].stat = TRADED;
  562.         break;
  563.     case TDSHIP:
  564.         /* use armynum to hold indicator */
  565.         ntn[cntry].nvy[(int)longval].smove = 0;
  566.         ntn[cntry].nvy[(int)longval].armynum = TRADED;
  567.         break;
  568.     }
  569. }
  570.  
  571. /* regain things that are up for bid */
  572. void
  573. takeback(cntry,item,longval)
  574. int cntry,item;
  575. long longval;
  576. {
  577.     switch(item)
  578.     {
  579.     case TDGOLD:
  580.         ntn[cntry].tgold += longval;
  581.         break;
  582.     case TDFOOD:
  583.         ntn[cntry].tfood += longval;
  584.         break;
  585.     case TDIRON:
  586.         ntn[cntry].tiron += longval;
  587.         break;
  588.     case TDJEWL:
  589.         ntn[cntry].jewels += longval;
  590.         break;
  591.     case TDLAND:
  592.         break;
  593.     case TDARMY:
  594.         ntn[cntry].arm[(int)longval].stat = DEFEND;
  595.         break;
  596.     case TDSHIP:
  597.         /* use armynum to hold indicator */
  598.         ntn[cntry].nvy[(int)longval].armynum = 0;
  599.         break;
  600.     }
  601. }
  602. #endif CONQUER
  603.  
  604. #ifdef ADMIN
  605. /* give things that were purchased from cntry1 to cntry2 */
  606. long
  607. tradeit(cntry1,cntry2,item,longval,extra)
  608. int cntry1,cntry2,item,extra;
  609. long longval;
  610. {
  611.     int unitnum=(-1),unitcount=0;
  612.     /* error for -1 returned */
  613.     long returnval=(-1);
  614.     switch(item)
  615.     {
  616.     case TDGOLD:
  617.         returnval = longval;
  618.         ntn[cntry1].tgold -= longval;
  619.         ntn[cntry2].tgold += longval * TRADECOST(20);
  620.         break;
  621.     case TDFOOD:
  622.         if (ntn[cntry1].tfood >= longval) {
  623.             returnval = longval;
  624.             ntn[cntry1].tfood -= longval;
  625.             ntn[cntry2].tfood += longval * TRADECOST(20);
  626.         }
  627.         break;
  628.     case TDIRON:
  629.         if (ntn[cntry1].tiron >= longval) {
  630.             ntn[cntry1].tiron -= longval;
  631.             ntn[cntry2].tiron += longval * TRADECOST(20);
  632.             returnval = longval;
  633.         }
  634.         break;
  635.     case TDJEWL:
  636.         if (ntn[cntry1].jewels >= longval) {
  637.             ntn[cntry1].jewels -= longval;
  638.             ntn[cntry2].jewels += longval * TRADECOST(20);
  639.             returnval = longval;
  640.         }
  641.         break;
  642.     case TDLAND:
  643.         if (sct[(int)longval][extra].owner==cntry1) {
  644.             sct[(int)longval][extra].owner = cntry2;
  645.             returnval = longval;
  646.         }
  647.         break;
  648.     case TDARMY:
  649.         /* find army number for cntry2 */
  650.         /* give army to cntry2 */
  651.         while(unitnum==(-1)&&unitcount<MAXARM) {
  652.             if (ntn[cntry2].arm[unitcount].sold<=0) {
  653.                 /* give army to cntry2 */
  654.                 ntn[cntry2].arm[unitcount].sold = ntn[cntry1].arm[extra].sold;
  655.                 ntn[cntry2].arm[unitcount].unittyp = ntn[cntry1].arm[extra].unittyp;
  656.                 ntn[cntry2].arm[unitcount].xloc = ntn[cntry2].capx;
  657.                 ntn[cntry2].arm[unitcount].yloc = ntn[cntry2].capy;
  658.                 ntn[cntry2].arm[unitcount].stat = DEFEND;
  659.                 ntn[cntry2].arm[unitcount].smove = 0;
  660.                 /* remove army from cntry1 */
  661.                 ntn[cntry1].arm[extra].sold = 0;
  662.                 ntn[cntry1].arm[extra].smove = 0;
  663.                 ntn[cntry1].arm[extra].stat = DEFEND;
  664.                 unitnum=unitcount;
  665.             }
  666.             unitcount++;
  667.         }
  668.         returnval=(long)unitnum;
  669.         break;
  670.     case TDSHIP:
  671.         /* give navy to cntry1 */
  672.         while(unitnum==(-1)&&unitcount<MAXARM){
  673.             if (ntn[cntry2].nvy[unitcount].merchant+ntn[cntry2].nvy[unitcount].warships <= 0) {
  674.                 /* give navy to cntry2 */
  675.                 ntn[cntry2].nvy[unitcount].warships = ntn[cntry1].nvy[extra].warships;
  676.                 ntn[cntry2].nvy[unitcount].merchant = ntn[cntry1].nvy[extra].merchant;
  677.                 ntn[cntry2].nvy[unitcount].crew = ntn[cntry1].nvy[extra].crew;
  678.                 ntn[cntry2].arm[unitcount].xloc = ntn[cntry1].nvy[extra].xloc;
  679.                 ntn[cntry2].arm[unitcount].yloc = ntn[cntry1].nvy[extra].yloc;
  680.                 ntn[cntry2].nvy[unitcount].armynum = 0;
  681.                 ntn[cntry2].nvy[unitcount].smove = 0;
  682.                 /* remove navy from cntry1 */
  683.                 ntn[cntry1].nvy[extra].smove = 0;
  684.                 ntn[cntry1].nvy[extra].merchant = 0;
  685.                 ntn[cntry1].nvy[extra].warships = 0;
  686.                 ntn[cntry1].nvy[extra].crew = 0;
  687.                 ntn[cntry1].nvy[extra].armynum = 0;
  688.                 unitnum=unitcount;
  689.             }
  690.             unitcount++;
  691.         }
  692.         returnval=(long)unitnum;
  693.         break;
  694.     }
  695.     return(returnval);
  696. }
  697.  
  698. long
  699. gettval(cntry1,cntry2,type,longval,extint)
  700. int cntry1, cntry2, extint;
  701. long longval;
  702. {
  703.     int returnval=(-1);
  704.     long armyvalue();
  705.  
  706.     switch(type) {
  707.     case TDGOLD:
  708.     case TDFOOD:
  709.     case TDIRON:
  710.     case TDJEWL:
  711.         returnval=longval;
  712.         break;
  713.     case TDLAND:
  714.         if (cntry2!=sct[(int)longval][extint].owner)
  715.         returnval=(long)tofood(sct[(int)longval][extint].vegetation,cntry1);
  716.         break;
  717.     case TDARMY:
  718.         if (armyvalue(cntry2,extint)>0)
  719.         returnval=armyvalue(cntry2,extint);
  720.         break;
  721.     case TDSHIP:
  722.         if (ntn[cntry2].nvy[extint].merchant+ntn[cntry2].nvy[extint].warships>0)
  723.         returnval=(long)(ntn[cntry2].nvy[extint].merchant+ntn[cntry2].nvy[extint].warships);
  724.         break;
  725.     }
  726.     return(returnval);
  727. }
  728.  
  729. /* this function sends detailed message to players */
  730. /* upon completion of a trade */
  731. void
  732. trademail(cntry1,cntry2,item1,item2,lvar1,lvar2,lvar3,lvar4)
  733. int cntry1,cntry2,item1,item2;
  734. long lvar1,lvar2,lvar3,lvar4;
  735. {
  736.     FILE *fp[2];
  737.     int count;
  738.     char cname[2][12],filename[2][80];
  739.  
  740.     sprintf(filename[0],"%s%d",msgfile,cntry1);
  741.     sprintf(filename[1],"%s%d",msgfile,cntry2);
  742.     strcpy(cname[0],ntn[cntry1].name);
  743.     strcpy(cname[1],ntn[cntry2].name);
  744.  
  745.     if ((fp[0]=fopen(filename[0],"a+"))==NULL) {
  746.         printf("error opening <%s>\n",filename[0]);
  747.         abrt();
  748.     }
  749.     if ((fp[1]=fopen(filename[1],"a+"))==NULL) {
  750.         printf("error opening <%s>\n",filename[1]);
  751.         abrt();
  752.     }
  753.  
  754.     for (count=0;count<2;count++) {
  755.         fprintf(fp[count],"%s Message to %s from Conquer Commerce Commision\n",cname[count],cname[count]);
  756.         fprintf(fp[count],"%s \n",cname[count]);
  757.         fprintf(fp[count],"%s   Trade transaction between %s and %s completed.",cname[count],cname[0],cname[1]);
  758.         if (item1<=TDJEWL)
  759.         fprintf(fp[count],"%s       Nation %s receives %ld %s\n",cname[count],cname[0],lvar1,commodities[item1]);
  760.         else if (item1==TDLAND)
  761.         fprintf(fp[count],"%s       Nation %s receives sector %ld, %ld\n",cname[count],cname[0],lvar1,lvar2);
  762.         else if (item1==TDARMY)
  763.         fprintf(fp[count],"%s       Nation %s receives army #%ld\n",cname[count],cname[0],lvar1);
  764.         else if (item1==TDSHIP)
  765.         fprintf(fp[count],"%s       Nation %s receives navy #%ld\n",cname[count],cname[0],lvar1);
  766.         if (item2<=TDJEWL)
  767.         fprintf(fp[count],"%s       Nation %s receives %ld %s\n",cname[count],cname[1],lvar3,commodities[item2]);
  768.         else if (item1==TDLAND)
  769.         fprintf(fp[count],"%s       Nation %s receives sector %ld, %ld\n",cname[count],cname[1],lvar3,lvar4);
  770.         else if (item1==TDARMY)
  771.         fprintf(fp[count],"%s       Nation %s receives army #%ld\n",cname[count],cname[1],lvar3);
  772.         else if (item1==TDSHIP)
  773.         fprintf(fp[count],"%s       Nation %s receives navy #%ld\n",cname[count],cname[1],lvar3);
  774.         fclose(fp[count]);
  775.     }
  776. }
  777. #endif ADMIN
  778.  
  779. /* routine to determine whether or not an army type is tradable */
  780. int
  781. tradable(cntry,armynum)
  782. int cntry,armynum;
  783. {
  784.     int oldcntry=country,returnval=FALSE;
  785.     country=cntry;
  786.     if ( ATYPE==A_MERCENARY || ATYPE==A_SEIGE || ATYPE==A_CATAPULT
  787.         || ATYPE==A_ELEPHANT || ATYPE>=MINMONSTER) returnval=TRUE;
  788.     country=oldcntry;
  789.     return(returnval);
  790. }
  791.  
  792. /* routine to determine commercial value of army */
  793. long armyvalue(cntry,unit)
  794. int cntry,unit;
  795. {
  796. #ifdef CONQUER
  797.     extern int unitattack[];
  798. #endif CONQUER
  799.     long returnval;
  800.     
  801.     returnval = ntn[cntry].arm[unit].sold*100 +
  802.         ntn[cntry].arm[unit].sold * unitattack[ntn[cntry].arm[unit].unittyp%100];
  803.     if (ntn[cntry].arm[unit].unittyp >= MINMONSTER) returnval+=ntn[cntry].arm[unit].sold*10;
  804.     returnval/=100;
  805.     return(returnval);
  806. }
  807.  
  808. void
  809. uptrade()
  810. {
  811.     FILE *tfile;
  812.     int count, itemnum=0, natn[MAXITM];
  813.     int type1[MAXITM], type2[MAXITM], deal[MAXITM], extra[MAXITM];
  814. #ifdef ADMIN
  815.     extern FILE *fnews;
  816.     void trademail();
  817.     int whobuy[MAXITM];
  818.     long tradeit(), buy1[MAXITM], buy2[MAXITM];
  819.     long price[MAXITM], gettval(), longval1, longval2;
  820. #endif ADMIN
  821.     long lvar1[MAXITM], lvar2[MAXITM];
  822. #ifdef CONQUER
  823.     void setaside(),takeback();
  824. #endif CONQUER
  825.  
  826.     /* initialize purchase list */
  827.     for (count=0; count<MAXITM; count++) {
  828.         deal[count]=(-1);
  829. #ifdef ADMIN
  830.         whobuy[count]=(-1);
  831.         price[count]=(-1);
  832. #endif ADMIN
  833.     }
  834.     /* open trading file */
  835.     if ((tfile = fopen(tradefile,"r")) == NULL) {
  836.         /* no commodities - no transactions */
  837.         return;
  838.     }
  839.     /* read in all of the transactions */
  840.     while(!feof(tfile)) {
  841.         fscanf(tfile,"%d %d %d %d %ld %ld %d\n",&deal[itemnum],
  842.             &natn[itemnum],&type1[itemnum],&type2[itemnum],&lvar1[itemnum],&lvar2[itemnum],&extra[itemnum]);
  843.         if (deal[itemnum]==NOSALE) {
  844.             /* remove item from sales list */
  845.             deal[type1[itemnum]]=NOSALE;
  846. #ifdef CONQUER
  847.             if (natn[itemnum]==country) takeback(country,type1[type1[itemnum]],lvar1[type1[itemnum]]);
  848. #endif CONQUER
  849.         } else if (deal[itemnum]==SELL) {
  850.             itemnum++;
  851. #ifdef CONQUER
  852.             if (natn[itemnum]==country) setaside(country,type2[itemnum],lvar1[itemnum]);
  853. #endif CONQUER
  854.         } else if (deal[itemnum]==BUY) {
  855. #ifdef ADMIN
  856.             if (deal[type1[itemnum]]==SELL) deal[type1[itemnum]]==BUY;
  857.             /* check for highest price for item */
  858.             if (price[type1[itemnum]]<gettval(natn[type1[itemnum]],natn[itemnum],type2[type1[itemnum]],lvar1[itemnum],(int)lvar2[itemnum])) {
  859.                 price[type1[itemnum]]=gettval(natn[type1[itemnum]],natn[itemnum],type2[type1[itemnum]],lvar1[itemnum],(int)lvar2[itemnum]);
  860.                 buy1[type1[itemnum]]=lvar1[itemnum];
  861.                 buy2[type1[itemnum]]=lvar2[itemnum];
  862.                 whobuy[type1[itemnum]]=natn[itemnum];
  863.             }
  864. #endif ADMIN
  865. #ifdef CONQUER
  866.             if (natn[itemnum]==country) setaside(country,type2[type1[itemnum]],lvar1[itemnum]);
  867. #endif CONQUER
  868.         }
  869.     }
  870.     fclose(tfile);
  871. #ifdef ADMIN
  872.     /* reopen the file for unsold commodities */
  873.     if ((tfile=fopen(tradefile,"w")) == NULL) {
  874.         /* error on opening file */
  875.         printf("Error opening <%s> for trade update\n",tradefile);
  876.         abrt();
  877.     }
  878.  
  879.     /* compute the trading */
  880.     for (count=0;count<itemnum;count++) {
  881.         if (deal[count]==SELL)
  882.             /* adjust the displayed value */
  883.             lvar1[count]=gettval(0,natn[count],type1[count],lvar1[count],extra[count]);
  884.             /* keep unsold items up for sale */
  885.             if(lvar1[count]>=0) fprintf(tfile,"%d %d %d %d %ld %ld %d\n", deal[count], natn[count],type1[count],type2[count],lvar1[count],lvar2[count],extra[count]);
  886.         else if (deal[count]==BUY) {
  887.             /* do the trading */
  888.             longval1 = tradeit(natn[count],whobuy[count],type1[count],lvar1[count],extra[count]);
  889.             if (longval1!=(-1)) longval2 = tradeit(whobuy[count],natn[count],type2[count],buy1[count],(int)buy2[count]);
  890.             if (longval1==(-1)) {
  891.                 /* abort due to seller */
  892.                 fprintf(fnews,"2.\tTrade between %s and %s breaks down due to %s.",
  893.                     ntn[natn[count]].name,ntn[whobuy[count]].name,tradefail[type1[count]]);
  894.             } else if (longval2==(-1)) {
  895.                 /* abort due to buyer */
  896.                 tradeit(whobuy[count],natn[count],type1[count],longval1,extra[count]);
  897.                 fprintf(fnews,"2.\tTrade between %s and %s breaks down due to %s.",
  898.                     ntn[whobuy[count]].name,ntn[natn[count]].name,tradefail[type2[count]]);
  899.                 /* place it on the list for next turn */
  900.                 /* adjust the displayed value */
  901.                 lvar1[count]=gettval(0,natn[count],type1[count],lvar1[count],extra[count]);
  902.                 if(lvar1[count]>=0) fprintf(tfile,"%d %d %d %d %ld %ld %d\n", SELL, natn[count],type1[count],type2[count],lvar1[count],lvar2[count],extra[count]);
  903.             } else {
  904.                 /* trade completed send mail */
  905.                 fprintf(fnews,"2.\tNation %s sells %s to %s for %s"
  906.                     ,ntn[natn[count]].name,commodities[type1[count]],ntn[whobuy[count]].name,commodities[type2[count]]);
  907.                 trademail(natn[count],whobuy[count],type1[count],
  908.                     type2[count],longval1,(long)extra[count],
  909.                     longval2,buy2[count]);
  910.             }
  911.         }
  912.     }
  913.     fclose(tfile);
  914. #endif ADMIN
  915. }
  916. #endif TRADE
  917.