home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / BEERSRC.ZIP / SHOP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-10  |  25.5 KB  |  921 lines

  1. // module shop.c
  2. // [c] copyright 1993 by ALPHA-HELIX
  3.  
  4. #include <mem.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7.  
  8. #include "sound.h"
  9. #include "xmode.h"
  10. #include "fileman.h"
  11. #include "baller.h"
  12.  
  13.  
  14. #define SHOPMAXARMS        5    // # of arms displayed on tresen.
  15. #define SHOPXSELL        208    // Position of seller area in shop.
  16. #define SHOPYSELL        137
  17. #define SHOPARMHI        30    // Assumed height of heighest weapon.
  18. #define SHOPXMENU        14    // Position of menu card.
  19. #define SHOPYMENU        106
  20. #define SHOPXEXIT        4    // Position of exit label in shop.
  21. #define SHOPYEXIT               59
  22. #define SHOPSPC            4    // Space between weapons.
  23. #define SHOPTEXT        210    // Y pos of weapon text.
  24. #define SHOPMTEXT        176    // X pos of money text.
  25. #define SHOPXPRICE              58
  26. #define SHOPYPRICE        105
  27.  
  28. #define MENUX            69      // Menucard font offsets
  29. #define MENUY            12
  30. #define MENCURX            48      // Menucard curser offsets
  31. #define MENCURY            27
  32. #define MENBACKX        48      // Menucard background
  33. #define MENBACKY        26
  34. #define MENUXEXIT        69      // Close card offsets
  35. #define MENUYEXIT        180
  36. #define MENUXPRICE        (XMAX - 65)
  37. #define MSTEP            2
  38.  
  39. #define NOFWEAPONS        10
  40.  
  41. #define WEAPONX0        (272 - 120)
  42. #define WEAPONY0        19
  43. #define WEAPONX1        272
  44. #define WEAPONY1        (19 + 80)
  45. #define WEAPONFLASH        (6*16)  // Flash color.
  46. #define WEAPONXTEXT        160
  47. #define WEAPONYTEXT        150
  48. #define WEAPONXMONEY        SHOPMTEXT
  49. #define WEAPONYMONEY        SHOPTEXT
  50. #define WEAPONXPTEXT            160
  51. #define WEAPONYP                170
  52. #define WEAPONXNAME             160
  53. #define WEAPONYNAME             150
  54. #define WEAPONXP                (XMAX - 40)
  55.  
  56. #define SELLXEXIT        20
  57. #define SELLYEXIT        25
  58. #define NOE            4
  59.  
  60.  
  61. /*------------------------------------------------------
  62. Function: defallarms
  63.  
  64. Description: Defines all active weapons around (x, y).
  65. ------------------------------------------------------*/
  66.  
  67. ulong defallarms(int x, int y)
  68. {
  69.    int     i;
  70.    ulong   xy;
  71.  
  72.    xy = getspritesize(intindex[weaponlst[0].arm.sprite]);
  73.    x = (x - ((int)xy / 2)) & 0xfffc; y = (y - ((int)(xy >> 16) / 2)) & 0xfffc;
  74.    xy = (ulong)y << 16 | x;
  75.    for (i = 0; i < nweapons; i++) {
  76.       weaponlst[i].object = defarm(weaponlst[i].dx + x, weaponlst[i].dy + y,
  77.                    &weaponlst[i].arm);
  78.    }
  79.  
  80.    return xy;
  81. }
  82.  
  83.  
  84. static void waitforrelease(void)
  85. {
  86.    while (pressedkeys) {
  87.       waitfortick(); updatescreen();
  88.    }
  89. }
  90.  
  91.  
  92. static void placeweapon(int n)
  93. {
  94.    int    handle;                   // Handle of new weapon.
  95.    int    saveflash;                    // To store old objectflashcolor.
  96.    int    dir, i;                       // Jupeidi.
  97.    int    abortkey;
  98.    int    x, y;                         // Coordinates of new weapon.
  99.    ulong  xy, ssize;
  100.    struct sprstrc *font;
  101.    void   *sell;
  102.  
  103.    setvanillapalette(0);
  104.    setpage(0); showpage(0); clearscreen();
  105.  
  106. // Load and display sell pcx.
  107.    sell = loadfile(datapool, "sell.pcx");
  108.    showpcx256(sell, 0);
  109.    unloadfile(sell);
  110.    copypage(0, 1);
  111.  
  112. // Load font
  113.    font = loadfile(datapool, "font1.spr");
  114.  
  115. // Define and display all active weapons.
  116.    xy = defallarms(WEAPONX0 + (WEAPONX1 - WEAPONX0)/2,
  117.           WEAPONY0 + (WEAPONY1 - WEAPONY0)/2);
  118.  
  119.    writetext(160 - (13*font->xs), 0, "PLACE WEAPON OR PRESS ESC!", font);
  120.  
  121.    x = (WEAPONX0 + 4) & 0xfffc;        // Start position of new weapon.
  122.    y = (WEAPONY0 + 4) & 0xfffc;
  123.    handle = defobject(intindex[weapon.arm[n].sprite], x, y, OBJ_HIGH);
  124.    ssize = getobjectsize(handle);
  125.  
  126.    saveflash = objflashcolor;
  127.    objflashcolor = WEAPONFLASH; dir = 2;
  128.    abortkey = 0;
  129.  
  130. // Display screen and begin placing
  131.    glowin(0);
  132.    waitforrelease();
  133.    do {
  134.       updatescreen();
  135.       objflashcolor += dir;
  136.       if ((objflashcolor < WEAPONFLASH) || (objflashcolor > WEAPONFLASH+15)) {
  137.      dir = -dir;
  138.      objflashcolor += dir;
  139.       }
  140.       flash(handle);
  141.  
  142.       if (key[key_up]) {
  143.      y -= 4;
  144.      if (y < ((WEAPONY0 + 4) & 0xfffc)) y += 4;
  145.      writetext(WEAPONXTEXT, WEAPONYTEXT, "       ", font);
  146.       }
  147.       if (key[key_down]) {
  148.      y += 4;
  149.      if (y > ((WEAPONY1 - (int)(ssize >> 16) - 4) & 0xfffc)) y -= 4;
  150.      writetext(WEAPONXTEXT, WEAPONYTEXT, "       ", font);
  151.       }
  152.       if (key[key_left]) {
  153.      x -= 4;
  154.      if (x < ((WEAPONX0 + 4) & 0xfffc)) x += 4;
  155.      writetext(WEAPONXTEXT, WEAPONYTEXT, "       ", font);
  156.       }
  157.       if (key[key_right]) {
  158.      x += 4;
  159.      if (x > ((WEAPONX1 - (int)ssize - 4) & 0xfffc)) x -= 4;
  160.      writetext(WEAPONXTEXT, WEAPONYTEXT, "       ", font);
  161.       }
  162.       if (key[key_fire]) {
  163.      abortkey = KEYSPACE;
  164.      for (i = 0; i < MAXARMS; i++) {
  165.         if (_arm[i].object != -1) {
  166.            if (crashtest(handle, _arm[i].object)) {
  167.           writetext(WEAPONXTEXT, WEAPONYTEXT, "OVERLAP", font);
  168.           abortkey = 0;
  169.            }
  170.         }
  171.      }
  172.       }
  173.       if (key[KEYESC]) {
  174.      abortkey = KEYESC;
  175.       }
  176.  
  177.       moveobject(handle, x, y);
  178.       waitfortick();
  179.  
  180.    } while (!abortkey);
  181.  
  182.    objflashcolor = saveflash;
  183.  
  184.    unloadfile(font);
  185.  
  186.    killobject(handle);
  187.    killallobjects();
  188.    killallbuddies();
  189.  
  190.    if (abortkey == KEYSPACE) {
  191.       weaponlst[nweapons].dx = x - (int)xy;
  192.       weaponlst[nweapons].dy = y - (int)(xy >> 16);
  193.       weaponlst[nweapons].arm = weapon.arm[n];
  194.       nweapons++;
  195.    }
  196.    glowout();
  197. }
  198.  
  199. static void payforweapon(int selected, struct sprstrc *f)
  200. {
  201.    int i;
  202.  
  203.    if(!(cheatlevel & CHEATMONEY))
  204.       for(i = money; money > (i-weapon.arm[selected].cost); money--){
  205.      writenumber(XMAX - (f->xs), SHOPTEXT, money-1, f);
  206.       }
  207. }
  208.  
  209. static void givemoneyback(int selected, struct sprstrc *f)
  210. {
  211.    int i;
  212.  
  213.    for(i = money; money < (i+(weapon.arm[selected].cost*3)/4); money++){
  214.       writenumber(XMAX - (f->xs), SHOPTEXT, money+1, f);
  215.    }
  216. }
  217.  
  218. static void turnsign(int *exit, int exitspr)
  219. {
  220. // Turn Exitsign in
  221.    if((*exit)<NOE && (*exit)>-2){
  222.       if((*exit)<NOE-1){
  223.      (*exit)++;
  224.      removesprite(exitspr, SELLXEXIT, SELLYEXIT);
  225.      putsprite(exitspr, SELLXEXIT, SELLYEXIT, *exit);
  226.       }else{
  227.      removesprite(exitspr, SELLXEXIT, SELLYEXIT);
  228.      putsprite(exitspr, SELLXEXIT, SELLYEXIT, *exit);
  229.      (*exit)++;
  230.       }
  231.    }
  232. // Turn Exitsign out
  233.    if((*exit)<-2){
  234.       (*exit)++;
  235.       removesprite(exitspr, SELLXEXIT, SELLYEXIT);
  236.       if((*exit)<-3) putsprite(exitspr, SELLXEXIT, SELLYEXIT, -(*exit)-4);
  237.    }
  238. }
  239.  
  240. /*------------------------------------------------------
  241. Function: sellweapon
  242.  
  243. Description: User may abandon one or more of his weapons.
  244. ------------------------------------------------------*/
  245.  
  246. static void sellweapon(void)
  247. {
  248.    int    selected;
  249.    int    saveflash;                    // To store old objectflashcolor.
  250.    int    dir;                          // Jupeidi.
  251.    int    i;
  252.    int      exitspr;
  253.    struct sprstrc *font;
  254.    void   *ptr;
  255.    int    exit;
  256.  
  257. /* exit:   -NOE-5 =>  Exitsign starts turning out
  258.        -2     =>  Exitsign is turned out
  259.        -1     =>  Exitsign starts turning in
  260.        NOE    =>  Exitsign is turned in
  261.        NOE+1  =>  Exit
  262. */
  263.  
  264.    setvanillapalette(0);
  265.    setpage(0); showpage(0);
  266.    clearscreen();
  267.  
  268. // Load and display sell pcx.
  269.    ptr = loadfile(datapool, "sell.pcx");
  270.    showpcx256(ptr, 0);
  271.    unloadfile(ptr);
  272.  
  273. // Load and define exit-sign
  274.    ptr = loadfile(datapool, "exit2.spr");
  275.    exitspr = defsprite(ptr, 4);
  276.    unloadfile(ptr);
  277.  
  278.    copypage(0, 1);
  279.  
  280.    font = loadfile(datapool, "font1.spr");
  281.  
  282. // Write Money the Player has and title
  283.    writetext(WEAPONXMONEY, WEAPONYMONEY, "YOUR MONEY", font);
  284.    writenumber(XMAX - (font->xs), WEAPONYMONEY, money, font);
  285.  
  286.    writetext(160 - (15*font->xs), 0, "CHOOSE WEAPON YOU WANT TO SELL", font);
  287.  
  288.    defallarms(WEAPONX0 + (WEAPONX1 - WEAPONX0)/2,
  289.           WEAPONY0 + (WEAPONY1 - WEAPONY0)/2);
  290.  
  291.    selected = 0; exit = -1;
  292.    saveflash = objflashcolor;
  293.    objflashcolor = WEAPONFLASH; dir = 2;
  294.    writetext(WEAPONXNAME, WEAPONYNAME, "EXIT", font);
  295.  
  296.    glowin(0);
  297.  
  298.    while ((nweapons > 1) && (exit != NOE+1)){
  299.  
  300.       waitforrelease();
  301.       do {
  302.      turnsign(&exit, exitspr);
  303. // Flash Weapon
  304.      if(selected != 0){
  305.         objflashcolor += dir;
  306.         if ((objflashcolor < WEAPONFLASH) || (objflashcolor > WEAPONFLASH+15)) {
  307.            dir = -dir;
  308.            objflashcolor += dir;
  309.         }
  310.         flash(weaponlst[selected].object);
  311.      }
  312. // Right Key was pressed
  313.      if (key[key_right]) {
  314.         selected++;
  315.         if (selected == 1){                    // Move from Exit
  316.            exit = (-exit)-4;
  317.            writetext(WEAPONXPTEXT, WEAPONYP, "VALUE:", font);
  318.         }
  319.         if (selected == nweapons){        // Move to Exit
  320.            selected = 0;
  321.            exit = ((exit==-2) ? (-1):((-exit)-4));
  322.            writetext(WEAPONXNAME, WEAPONYNAME, "EXIT                ", font);
  323.            writetext(WEAPONXPTEXT, WEAPONYP, "                      ", font);
  324.         }else{
  325.            writetext(WEAPONXNAME, WEAPONYNAME, "                    ", font);
  326.            writetext(WEAPONXNAME, WEAPONYNAME,
  327.             weaponlst[selected].arm.armname , font);
  328.            writenumber(WEAPONXP, WEAPONYP,
  329.             (weaponlst[selected].arm.cost*3)/4, font);
  330.         }
  331.         while (key[key_right]) {
  332.            waitfortick();
  333.            updatescreen();
  334.            turnsign(&exit, exitspr);
  335.         }
  336.      }
  337. // Left Key was pressed
  338.      if (key[key_left]) {
  339.         selected--;
  340.         if (selected < 0){                   // Move from Exit
  341.            exit = (-exit)-4;
  342.            selected = nweapons - 1;
  343.            writetext(WEAPONXPTEXT, WEAPONYP, "VALUE:", font);
  344.         }
  345.         if (selected == 0){                    // Move to Exit
  346.            exit = ((exit==-2) ? (-1):((-exit)-4));
  347.            writetext(WEAPONXNAME, WEAPONYNAME, "EXIT                ", font);
  348.            writetext(WEAPONXPTEXT, WEAPONYP, "                      ", font);
  349.         }else{
  350.            writetext(WEAPONXNAME, WEAPONYNAME, "                    ", font);
  351.            writetext(WEAPONXNAME, WEAPONYNAME,
  352.             weaponlst[selected].arm.armname , font);
  353.            writenumber(WEAPONXP, WEAPONYP,
  354.             (weaponlst[selected].arm.cost*3)/4, font);
  355.         }
  356.         while (key[key_left]) {
  357.            waitfortick();
  358.            updatescreen();
  359.            turnsign(&exit, exitspr);
  360.         }
  361.      }
  362.      waitfortick();
  363.      updatescreen();
  364.       } while (!key[key_fire]);
  365.  
  366.       if (selected != 0) {
  367.      givemoneyback(selected, font);
  368.      abandonobject(weaponlst[selected].object);
  369.      nweapons--;            // Kill selected weapon from list.
  370.      for (i = selected; i < nweapons; i++) {
  371.         weaponlst[i] = weaponlst[i+1];
  372.      }
  373.      selected = 0;
  374.      exit = ((exit==-2) ? (-1):((-exit)-4));
  375.      writetext(WEAPONXNAME, WEAPONYNAME, "EXIT                ", font);
  376.      writetext(WEAPONXPTEXT, WEAPONYP, "                      ", font);
  377.       } else {
  378.      exit = NOE+1;
  379.       }
  380.    }
  381.    unloadfile(font);
  382.    killsprite(exitspr);
  383.  
  384.    objflashcolor = saveflash;
  385.  
  386.    killallobjects();
  387.    killallbuddies();
  388.  
  389.    glowout();
  390.    clearscreen();
  391.    setstandardpalette();
  392.  
  393. }
  394.  
  395. // Checks if player can buy Weapon or not
  396.  
  397. static int checkforexit(int selected, struct sprstrc *font)
  398. {
  399.    if (weapon.arm[selected].cost > money) {
  400.       writetext(0, SHOPTEXT, "NOT ENOUGH MONEY", font);
  401.       return FALSE;
  402.    }
  403.    if ((weapon.arm[selected].flags & W_SPEEDUP) && (shipspeed>=MAXSHIPSPEED)) {
  404.       writetext(0, SHOPTEXT, "ONLY 2 SPEEDUPS", font);
  405.       return FALSE;
  406.    }
  407.    if (!(weapon.arm[selected].flags & W_ISWEAPON)) return TRUE;
  408.    if (nweapons >= MAXARMS) {
  409.       writetext(0, SHOPTEXT, "NO PLACE TO PUT", font);
  410.       return FALSE;
  411.    }
  412.  
  413.    return TRUE;
  414. }
  415.  
  416.  
  417. /*------------------------------------------------------
  418. Function: menucard
  419.  
  420. Description: Shows all available upgrades, powerups,
  421.          bursters, smashers, speeders, ...
  422.          ... and weapons.
  423. ------------------------------------------------------*/
  424. static void menucard(void)
  425. {
  426.    int    i, y, delta;
  427.    int    yw, ye;            // y-pos of weapon- and extra list.
  428.    int    selected, quit;
  429.    int    narms;
  430.    char   text[29];
  431.    struct sprstrc *font1, *font2;
  432.    int      weaponnumber[NOFWEAPONS];
  433.    int       pointobj, pointspr;
  434.    int      backobj, backspr;
  435.    void   *ptr;
  436.  
  437. // Load Datas
  438.    setvanillapalette(0);
  439.    showpage(0); setpage(0); clearscreen();
  440.  
  441. // Load and display menucard pcx.
  442.    ptr = loadfile(datapool, "menucard.pcx");
  443.    showpcx256(ptr, 0);
  444.    unloadfile(ptr);
  445.  
  446. // Load Objects (Cursor and its background)
  447.    ptr = loadfile(datapool, "mencur2.spr");
  448.    pointspr = defsprite(ptr, 4);
  449.    unloadfile(ptr);
  450.  
  451.    pointobj = defobject(pointspr, MENCURX, MENCURY, OBJ_HIGH);
  452.  
  453.    ptr = loadfile(datapool, "menback.spr");
  454.    backspr = defsprite(ptr, 4);
  455.    unloadfile(ptr);
  456.  
  457.    backobj = defobject(backspr, MENBACKX, MENBACKY, OBJ_LOW);
  458.  
  459. // Load Fonts
  460.    font1 = loadfile(datapool, "mfont.spr");
  461.    font2 = loadfile(datapool, "font1.spr");
  462.  
  463.    copypage(0, 1);
  464.  
  465. // Making Menucard
  466.  
  467.    writetext(MENUXEXIT, MENUYEXIT, "BACK TO SHOP", font1);
  468.  
  469.    y = MENUY;
  470.    writetext(MENUX, y, "COOL AND FRESH DRINKS", font1);
  471.    yw = y += font1->ys + 6;
  472.    narms = selected = 0;
  473.    for (i = min(weapon.narms, SHOPMAXARMS); i < weapon.narms; i++) {
  474.       if (weapon.arm[i].flags & W_ISWEAPON) {
  475.      setmem(text, 28, '.'); text[28] = '\0';
  476.      memcpy(text, weapon.arm[i].armname, strlen(weapon.arm[i].armname));
  477.      writetext(MENUX, y, text, font1);
  478.      writenumber(MENUXPRICE, y, weapon.arm[i].cost, font1);
  479.      y += font1->ys + 3;
  480.      narms++;
  481.      weaponnumber[++selected] = i;
  482.       }
  483.    }
  484.  
  485.    y += 8;
  486.    writetext(MENUX, y, "SCHNAPS BONUS", font1);
  487.    ye = y += font1->ys + 6;
  488.    for (i = min(weapon.narms, SHOPMAXARMS); i < weapon.narms; i++) {
  489.       if (!(weapon.arm[i].flags & W_ISWEAPON)) {
  490.      setmem(text, 28, '.'); text[28] = '\0';
  491.      memcpy(text, weapon.arm[i].armname, strlen(weapon.arm[i].armname));
  492.      writetext(MENUX, y, text, font1);
  493.      writenumber(MENUXPRICE, y, weapon.arm[i].cost, font1);
  494.      y += font1->ys + 3;
  495.      weaponnumber[++selected] = i;
  496.       }
  497.    }
  498.  
  499. // Write players money
  500.  
  501.    writetext(SHOPMTEXT, SHOPTEXT, "YOUR MONEY", font2);
  502.    writenumber(XMAX - (font2->xs), SHOPTEXT, money, font2);
  503.  
  504.    glowin(0);
  505.  
  506.    selected = 1;
  507.  
  508.    do {
  509.  
  510. // Let the selection begin
  511.  
  512.       y = yw;
  513.       waitforrelease();
  514.       do {
  515.      updatescreen();
  516.      if(key[key_up]){                                   // Up
  517.         writetext(0, SHOPTEXT, "                 ", font2);
  518.         if(selected > 1){
  519.            selected--;
  520.            if (selected == narms)
  521.           delta = ye - yw - ((narms-1)*(font1->ys+3));
  522.            else if(selected == weapon.narms - min(weapon.narms, SHOPMAXARMS))
  523.           delta = MENUYEXIT - ye - ((selected-1-narms)*font1->ys+3);
  524.            else
  525.           delta = font1->ys+3;
  526.            for (i = 0; i < (delta / MSTEP); i++) {
  527.           moveobjectdelta(pointobj, 0, -MSTEP);
  528.           waitfortick();
  529.           updatescreen();
  530.            }
  531.         }else{
  532.            selected = weapon.narms - min(weapon.narms, SHOPMAXARMS) + 1;
  533.            moveobject(pointobj, MENCURX, MENUYEXIT);
  534.            waitforrelease();
  535.         }
  536.      }
  537.      if(key[key_down]){                                 // Down
  538.         writetext(0, SHOPTEXT, "                 ", font2);
  539.         if(selected < weapon.narms-min(weapon.narms, SHOPMAXARMS)+1){
  540.            selected++;
  541.            if (selected == (narms+1))
  542.           delta = ye - yw - ((narms-1)*(font1->ys+3));
  543.            else if(selected == weapon.narms - min(weapon.narms, SHOPMAXARMS)+1)
  544.           delta = MENUYEXIT - ye - ((selected-2-narms)*font1->ys+3);
  545.            else
  546.           delta = font1->ys+3;
  547.            for (i = 0; i < (delta / MSTEP); i++) {
  548.           moveobjectdelta(pointobj, 0, MSTEP);
  549.           waitfortick();
  550.           updatescreen();
  551.            }
  552.         }else{
  553.            selected = 1;
  554.            moveobject(pointobj, MENCURX, MENCURY);
  555.            waitforrelease();
  556.         }
  557.      }
  558.      waitfortick();
  559.      if (key[key_fire] && selected != weapon.narms-min(weapon.narms, SHOPMAXARMS)+1)
  560.         quit = checkforexit(weaponnumber[selected], font2);
  561.       } while (!((key[key_fire]) &&
  562.          ((selected == (weapon.narms-min(weapon.narms, SHOPMAXARMS)+1)) ||
  563.          quit)));
  564.  
  565. // Something was selected
  566.       if(selected != (weapon.narms-min(weapon.narms, SHOPMAXARMS)+1)) // Not Exit
  567.      if (weapon.arm[weaponnumber[selected]].flags & W_ISWEAPON) {
  568.         payforweapon(weaponnumber[selected], font2);
  569.         glowout();
  570.         killobject(backobj);
  571.         killobject(pointobj);
  572.         clearscreen();
  573.         setstandardpalette();
  574.         placeweapon(weaponnumber[selected]);
  575.  
  576.         selected = 1;
  577.  
  578. // Load Datas
  579.         setvanillapalette(0);
  580.         showpage(0); setpage(0); clearscreen();
  581.  
  582. // Load and display menucard pcx.
  583.         ptr = loadfile(datapool, "menucard.pcx");
  584.         showpcx256(ptr, 0);
  585.         unloadfile(ptr);
  586.  
  587. // Set Cursorposition
  588.         pointobj = defobject(pointspr, MENCURX, MENCURY, OBJ_HIGH);
  589.         backobj = defobject(backspr, MENBACKX, MENBACKY, OBJ_LOW);
  590.  
  591.         copypage(0, 1);
  592.  
  593. // Making Menucard
  594.  
  595.         writetext(MENUXEXIT, MENUYEXIT, "BACK TO SHOP", font1);
  596.         y = MENUY;
  597.         writetext(MENUX, y, "GETRAENKE UND WAFFEN", font1);
  598.         yw = y += font1->ys + 6;
  599.         for (i = min(weapon.narms, SHOPMAXARMS); i < weapon.narms; i++) {
  600.            if (weapon.arm[i].flags & W_ISWEAPON) {
  601.           setmem(text, 28, '.'); text[28] = '\0';
  602.           memcpy(text, weapon.arm[i].armname, strlen(weapon.arm[i].armname));
  603.           writetext(MENUX, y, text, font1);
  604.           writenumber(MENUXPRICE, y, weapon.arm[i].cost, font1);
  605.           y += font1->ys + 3;
  606.            }
  607.         }
  608.  
  609.         y += 8;
  610.         writetext(MENUX, y, "SCHNAPS BONUS", font1);
  611.         ye = y += font1->ys + 6;
  612.         for (i = min(weapon.narms, SHOPMAXARMS); i < weapon.narms; i++) {
  613.            if (!(weapon.arm[i].flags & W_ISWEAPON)) {
  614.           setmem(text, 28, '.'); text[28] = '\0';
  615.           memcpy(text, weapon.arm[i].armname, strlen(weapon.arm[i].armname));
  616.           writetext(MENUX, y, text, font1);
  617.           writenumber(MENUXPRICE, y, weapon.arm[i].cost, font1);
  618.           y += font1->ys + 3;
  619.            }
  620.         }
  621.  
  622. // Write players money
  623.         writetext(SHOPMTEXT, SHOPTEXT, "YOUR MONEY", font2);
  624.         writenumber(XMAX - (font2->xs), SHOPTEXT, money, font2);
  625.  
  626.         glowin(0);
  627.  
  628.      } else {
  629.         payforweapon(weaponnumber[selected], font2);
  630.         switch (weapon.arm[weaponnumber[selected]].flags) {
  631.            case W_SPEEDUP:
  632.           shipspeed += 2;
  633.           break;
  634.            case W_EXTRALIFE:
  635.           lifes++;
  636.           break;
  637.  
  638.         }
  639.      }
  640.  
  641.    } while(selected != weapon.narms - min(weapon.narms, SHOPMAXARMS) + 1);
  642.  
  643.    glowout();
  644.  
  645.    killobject(backobj);
  646.    killsprite(backspr);
  647.    killobject(pointobj);
  648.    killsprite(pointspr);
  649.    unloadfile(font2);
  650.    unloadfile(font1);
  651.  
  652.    clearscreen();
  653.    setstandardpalette();
  654. }
  655.  
  656.  
  657. static void placeprice(long price, struct sprstrc *font)
  658. {
  659.    int j, xs, x, i = 0;
  660.    int zahl;
  661.  
  662.    x = SHOPXPRICE;
  663.    xs = font->xs;
  664.    for(j = 0; j < 2; j++){
  665.       putspritedirect(font, x, SHOPYPRICE, (price % 10));
  666.       price /= 10;
  667.       x -= xs;
  668.    }
  669.    putspritedirect(font, x, SHOPYPRICE, 10);  // Write point
  670.    for(; j < 5; j++){
  671.       x -= xs;
  672.       zahl = price % 10;
  673.       if(zahl != 0 || j == 2){
  674.      putspritedirect(font, x, SHOPYPRICE, zahl);
  675.      if(i!=0) for(; i > 0; i--) putspritedirect(font, x+i*xs, SHOPYPRICE, 0);
  676.      i = 0;
  677.       }else{
  678.      putspritedirect(font, x, SHOPYPRICE, 11);     // Clear unused digits
  679.      i ++;
  680.       }
  681.       price /= 10;
  682.    }
  683. }
  684.  
  685. static void closeshop(struct sprstrc *pf, struct sprstrc *f, int obj, int espr, int pspr)
  686. {
  687.    glowout();
  688.  
  689.    unloadfile(pf);
  690.    unloadfile(f);
  691.    killobject(obj);
  692.    killsprite(espr);
  693.    killsprite(pspr);
  694.  
  695. }
  696.  
  697. /*------------------------------------------------------
  698. Function: buyweapon
  699.  
  700. Description: Opens the shop screen and let the user
  701.          choose a weapon. If a weapon was bought,
  702.          it must be placed. If 'exit' was selected,
  703.          TRUE is returned.
  704. ------------------------------------------------------*/
  705.  
  706. static int buyweapon(void)
  707. {
  708.    int     x, selected;            // x pos and # of selected weapon.
  709.    int     i, j, spr;                   // Lall variablen.
  710.    int     narms;            // # of arms displayed on tresen.
  711.    ulong   xy;                          // Function return of "getspritesize".
  712.    int     pointspr, obj, exitspr;
  713.    int     yspoint;
  714.    void    *pointer;            // Picture data.
  715.    struct  sprstrc *font, *pfont;
  716.    int        value;            // Value of selected weapon
  717.    int     ok;
  718.  
  719.    setvanillapalette(0);        // Go black.
  720.    setpage(0); showpage(0);
  721.    clearscreen();
  722.  
  723. // Load and display store pcx.
  724.    pointer = loadfile(datapool, "store.pcx");
  725.    showpcx256(pointer, 0);
  726.    unloadfile(pointer);
  727.  
  728. // Load and define arrow pointer.
  729.    pointer = loadfile(datapool, "arrow.spr");
  730.    pointspr = defsprite(pointer, 2);
  731.    unloadfile(pointer);
  732.  
  733. // Load and define exit-sign
  734.    pointer = loadfile(datapool, "exit.spr");
  735.    exitspr = defsprite(pointer, 4);
  736.    unloadfile(pointer);
  737.  
  738. // Display weapons on 'tresen'.
  739.    narms = min(weapon.narms, SHOPMAXARMS) - 1;
  740.    for (i = 1, x = SHOPXSELL; i <= narms; i++) {
  741.       if (weapon.arm[i].flags & W_ISWEAPON) {
  742.      spr = intindex[weapon.arm[i].sprite];
  743.      xy = getspritesize(spr);
  744.      putsprite(spr, x, SHOPYSELL - (xy >> 16), 0);
  745.      x += (int)xy + SHOPSPC;
  746.       } else {
  747.      narms--;
  748.       }
  749.    }
  750.  
  751.    copypage(0, 1);            // Copy to second page not to
  752.                     // have flickering animation.
  753.  
  754. // Open fonts
  755.    font = loadfile(datapool, "font1.spr");
  756.    pfont = loadfile(datapool, "cfont.spr");
  757.  
  758. // Set Pointer to selected weapon;
  759. // selected = -1 : exit
  760. // selected =  0 : menu card
  761. // selected >  0 : weapons
  762.    x = SHOPXSELL; selected = 1;
  763.    xy = getspritesize(pointspr);
  764. // Adjust arrow position according to it's x-size.
  765.    x -= (int)xy / 2;
  766.    x += (int)getspritesize(intindex[weapon.arm[selected].sprite]) / 2;
  767.    yspoint = (xy >> 16);
  768.    obj = defobject(pointspr, x, SHOPYSELL-SHOPARMHI-yspoint, OBJ_LOW);
  769.    writetext(0, SHOPTEXT, weapon.arm[selected].armname, font);
  770.    value = weapon.arm[selected].cost;
  771.    placeprice(value, pfont);
  772.  
  773. // Display money the player has
  774.    writetext(SHOPMTEXT, SHOPTEXT, "YOUR MONEY", font);
  775.    writenumber(XMAX - (font->xs), SHOPTEXT, money, font);
  776.  
  777.    glowin(0);                // Finally show shop picture.
  778.  
  779.  
  780. // Move pointer according to the pressed keys.
  781.    waitforrelease();
  782.    do {
  783.       ok = 1;
  784.       updatescreen();
  785.  
  786.       if ((key[key_right]) && selected < narms) {
  787.      writetext(0, SHOPTEXT, "                 ", font);
  788.      selected++;
  789.      switch (selected) {
  790.         case 0:            // Move from exit to menu card.
  791.            killobject(obj);
  792.            writetext(0, SHOPTEXT, "MENU CARD", font);
  793.            putsprite(exitspr, SHOPXEXIT, SHOPYEXIT, 0);
  794.            waitfortick();
  795.            updatescreen();
  796.            putsprite(exitspr, SHOPXEXIT, SHOPYEXIT, 0);
  797.            obj = defobject(pointspr, SHOPXMENU, SHOPYMENU - yspoint, OBJ_LOW);
  798.            waitforrelease();
  799.            break;
  800.         case 1:            // Move from menu to weapons.
  801.            moveobject(obj, x, SHOPYSELL - SHOPARMHI - yspoint);
  802.            writetext(0, SHOPTEXT, weapon.arm[1].armname, font);
  803.            value = weapon.arm[1].cost;
  804.            placeprice(value, pfont);
  805.            waitforrelease();
  806.            break;
  807.         default:
  808.            j = (int)getspritesize(intindex[weapon.arm[selected-1].sprite])/2
  809.          + (int)getspritesize(intindex[weapon.arm[selected].sprite])/2
  810.          + SHOPSPC;
  811.            for (i = 0; i < j; i+=2) {
  812.           x += 2; moveobjectdelta(obj, 2, 0);
  813.           waitfortick(); updatescreen();
  814.            }
  815.            writetext(0, SHOPTEXT, weapon.arm[selected].armname, font);
  816.            value = weapon.arm[selected].cost;
  817.            placeprice(value, pfont);
  818.            break;
  819.      }
  820.       }
  821.  
  822.       if ((key[key_left]) && selected > -1) {
  823.      writetext(0, SHOPTEXT, "                 ", font);
  824.      selected--;
  825.      switch (selected) {
  826.         case -1:            // Move from menu-card to exit.
  827.            killobject(obj);
  828.            obj = defobject(exitspr, SHOPXEXIT, SHOPYEXIT, OBJ_LOW);
  829.            writetext(0, SHOPTEXT, "EXIT SHOP", font);
  830.            waitforrelease();
  831.            break;
  832.         case 0:            // Move from weapons to menu.
  833.            moveobject(obj, SHOPXMENU, SHOPYMENU - yspoint);
  834.            writetext(0, SHOPTEXT, "MENU CARD", font);
  835.            value = 0;
  836.            placeprice(value, pfont);
  837.            waitforrelease();
  838.            break;
  839.         default:
  840.            j = (int)getspritesize(intindex[weapon.arm[selected+1].sprite])/2
  841.          + (int)getspritesize(intindex[weapon.arm[selected].sprite])/2
  842.          + SHOPSPC;
  843.            for (i = 0; i < j; i+=2) {
  844.           x -= 2; moveobjectdelta(obj, -2, 0);
  845.           waitfortick(); updatescreen();
  846.            }
  847.            writetext(0, SHOPTEXT, weapon.arm[selected].armname, font);
  848.            value = weapon.arm[selected].cost;
  849.            placeprice(value, pfont);
  850.            break;
  851.      }
  852.       }
  853.  
  854.  
  855.       waitfortick();
  856.  
  857.       if (key[key_fire]) {
  858.      if (selected < 1) break;
  859.      if (value > money) {
  860.         ok = 0;
  861.         writetext(0, SHOPTEXT, "NOT ENOUGH MONEY", font);
  862.      }
  863.      if (nweapons >= MAXARMS) {
  864.         ok = 0;
  865.         writetext(0, SHOPTEXT, "NO PLACE TO PUT", font);
  866.      }
  867.            }
  868.    } while (!key[key_fire] || !ok);
  869.  
  870. // Player has pressed fire.
  871.  
  872.    switch (selected) {
  873.       case -1: closeshop(pfont, font, obj, exitspr, pointspr);
  874.            clearscreen();
  875.            setstandardpalette();
  876.            return TRUE;
  877.       case  0: closeshop(pfont, font, obj, exitspr, pointspr);
  878.            menucard();
  879.            return FALSE;
  880.       default: payforweapon(selected, font);             // Let Player pay for new weapon
  881.            closeshop(pfont, font, obj, exitspr, pointspr);
  882.            placeweapon(selected);
  883.            clearscreen();
  884.            setstandardpalette();
  885.            return FALSE;
  886.    }
  887.  
  888. }
  889.  
  890.  
  891. void weaponmanager(void)
  892. {
  893.    long   deltam;
  894.    struct sndstrc *snd;
  895.  
  896.  
  897. // Calculate money
  898.    deltam = (score - scoreold +1500) / 2500;
  899.    deltam *= 5;
  900.    money += deltam;
  901.    scoreold = score;
  902.    if(cheatlevel & CHEATMONEY) money = 999995;
  903.  
  904. // Sell weapons
  905.  
  906.    snd = loadfile(datapool, "sell.snd");
  907.    playloop(snd);
  908.    if (nweapons > 1) sellweapon();
  909.    haltsound();
  910.    unloadfile(snd);
  911.  
  912. // Buy weapons
  913.  
  914.    snd = loadfile(datapool, "buy.snd");
  915.    playloop(snd);
  916.    while (!buyweapon());
  917.    haltsound();
  918.    unloadfile(snd);
  919. }
  920.  
  921.