Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. // WL_ACT1.C
  2.  
  3. #include "wl_def.h"
  4. #pragma hdrstop
  5.  
  6. /*
  7. =============================================================================
  8.  
  9.                                                         STATICS
  10.  
  11. =============================================================================
  12. */
  13.  
  14.  
  15. statobj_t       statobjlist[MAXSTATS];
  16. statobj_t       *laststatobj;
  17.  
  18.  
  19. struct
  20. {
  21.     short      picnum;
  22.     wl_stat_t  type;
  23.     uint32_t   specialFlags;    // they are ORed to the statobj_t flags
  24. } statinfo[] =
  25. {
  26.     {SPR_STAT_0},                           // puddle          spr1v
  27.     {SPR_STAT_1,block},                     // Green Barrel    "
  28.     {SPR_STAT_2,block},                     // Table/chairs    "
  29.     {SPR_STAT_3,block,FL_FULLBRIGHT},       // Floor lamp      "
  30.     {SPR_STAT_4,none,FL_FULLBRIGHT},        // Chandelier      "
  31.     {SPR_STAT_5,block},                     // Hanged man      "
  32.     {SPR_STAT_6,bo_alpo},                   // Bad food        "
  33.     {SPR_STAT_7,block},                     // Red pillar      "
  34.     //
  35.     // NEW PAGE
  36.     //
  37.     {SPR_STAT_8,block},                     // Tree            spr2v
  38.     {SPR_STAT_9},                           // Skeleton flat   "
  39.     {SPR_STAT_10,block},                    // Sink            " (SOD:gibs)
  40.     {SPR_STAT_11,block},                    // Potted plant    "
  41.     {SPR_STAT_12,block},                    // Urn             "
  42.     {SPR_STAT_13,block},                    // Bare table      "
  43.     {SPR_STAT_14,none,FL_FULLBRIGHT},       // Ceiling light   "
  44.     #ifndef SPEAR
  45.     {SPR_STAT_15},                          // Kitchen stuff   "
  46.     #else
  47.     {SPR_STAT_15,block},                    // Gibs!
  48.     #endif
  49.     //
  50.     // NEW PAGE
  51.     //
  52.     {SPR_STAT_16,block},                    // suit of armor   spr3v
  53.     {SPR_STAT_17,block},                    // Hanging cage    "
  54.     {SPR_STAT_18,block},                    // SkeletoninCage  "
  55.     {SPR_STAT_19},                          // Skeleton relax  "
  56.     {SPR_STAT_20,bo_key1},                  // Key 1           "
  57.     {SPR_STAT_21,bo_key2},                  // Key 2           "
  58.     {SPR_STAT_22,block},                    // stuff             (SOD:gibs)
  59.     {SPR_STAT_23},                          // stuff
  60.     //
  61.     // NEW PAGE
  62.     //
  63.     {SPR_STAT_24,bo_food},                  // Good food       spr4v
  64.     {SPR_STAT_25,bo_firstaid},              // First aid       "
  65.     {SPR_STAT_26,bo_clip},                  // Clip            "
  66.     {SPR_STAT_27,bo_machinegun},            // Machine gun     "
  67.     {SPR_STAT_28,bo_chaingun},              // Gatling gun     "
  68.     {SPR_STAT_29,bo_cross},                 // Cross           "
  69.     {SPR_STAT_30,bo_chalice},               // Chalice         "
  70.     {SPR_STAT_31,bo_bible},                 // Bible           "
  71.     //
  72.     // NEW PAGE
  73.     //
  74.     {SPR_STAT_32,bo_crown},                 // crown           spr5v
  75.     {SPR_STAT_33,bo_fullheal,FL_FULLBRIGHT},// one up          "
  76.     {SPR_STAT_34,bo_gibs},                  // gibs            "
  77.     {SPR_STAT_35,block},                    // barrel          "
  78.     {SPR_STAT_36,block},                    // well            "
  79.     {SPR_STAT_37,block},                    // Empty well      "
  80.     {SPR_STAT_38,bo_gibs},                  // Gibs 2          "
  81.     {SPR_STAT_39,block},                    // flag            "
  82.     //
  83.     // NEW PAGE
  84.     //
  85.     #ifndef SPEAR
  86.     {SPR_STAT_40,block},                    // Call Apogee          spr7v
  87.     #else
  88.     {SPR_STAT_40},                          // Red light
  89.     #endif
  90.     //
  91.     // NEW PAGE
  92.     //
  93.     {SPR_STAT_41},                          // junk            "
  94.     {SPR_STAT_42},                          // junk            "
  95.     {SPR_STAT_43},                          // junk            "
  96.     #ifndef SPEAR
  97.     {SPR_STAT_44},                          // pots            "
  98.     #else
  99.     {SPR_STAT_44,block},                    // Gibs!
  100.     #endif
  101.     {SPR_STAT_45,block},                    // stove           " (SOD:gibs)
  102.     {SPR_STAT_46,block},                    // spears          " (SOD:gibs)
  103.     {SPR_STAT_47},                          // vines           "
  104.     //
  105.     // NEW PAGE
  106.     //
  107.     #ifdef SPEAR
  108.     {SPR_STAT_48,block},                    // marble pillar
  109.     {SPR_STAT_49,bo_25clip},                // bonus 25 clip
  110.     {SPR_STAT_50,block},                    // truck
  111.     {SPR_STAT_51,bo_spear},                 // SPEAR OF DESTINY!
  112.     #endif
  113.  
  114.     {SPR_STAT_26,bo_clip2},                 // Clip            "
  115. #ifdef USE_DIR3DSPR
  116.     // These are just two examples showing the new way of using dir 3d sprites.
  117.     // You can find the allowed values in the objflag_t enum in wl_def.h.
  118.     {SPR_STAT_47,none,FL_DIR_VERT_MID},
  119.     {SPR_STAT_47,block,FL_DIR_HORIZ_MID},
  120. #endif
  121.     {-1}                                    // terminator
  122. };
  123.  
  124. /*
  125. ===============
  126. =
  127. = InitStaticList
  128. =
  129. ===============
  130. */
  131.  
  132. void InitStaticList (void)
  133. {
  134.     laststatobj = &statobjlist[0];
  135. }
  136.  
  137.  
  138.  
  139. /*
  140. ===============
  141. =
  142. = SpawnStatic
  143. =
  144. ===============
  145. */
  146.  
  147. void SpawnStatic (int tilex, int tiley, int type)
  148. {
  149.     laststatobj->shapenum = statinfo[type].picnum;
  150.     laststatobj->tilex = tilex;
  151.     laststatobj->tiley = tiley;
  152.     laststatobj->visspot = &spotvis[tilex][tiley];
  153.  
  154.     switch (statinfo[type].type)
  155.     {
  156.         case block:
  157.             actorat[tilex][tiley] = (objtype *) 64;          // consider it a blocking tile
  158.         case none:
  159.             laststatobj->flags = 0;
  160.             break;
  161.  
  162.         case    bo_cross:
  163.         case    bo_chalice:
  164.         case    bo_bible:
  165.         case    bo_crown:
  166.         case    bo_fullheal:
  167.             if (!loadedgame)
  168.                 gamestate.treasuretotal++;
  169.  
  170.         case    bo_firstaid:
  171.         case    bo_key1:
  172.         case    bo_key2:
  173.         case    bo_key3:
  174.         case    bo_key4:
  175.         case    bo_clip:
  176.         case    bo_25clip:
  177.         case    bo_machinegun:
  178.         case    bo_chaingun:
  179.         case    bo_food:
  180.         case    bo_alpo:
  181.         case    bo_gibs:
  182.         case    bo_spear:
  183.             laststatobj->flags = FL_BONUS;
  184.             laststatobj->itemnumber = statinfo[type].type;
  185.             break;
  186.     }
  187.  
  188.     laststatobj->flags |= statinfo[type].specialFlags;
  189.  
  190.     laststatobj++;
  191.  
  192.     if (laststatobj == &statobjlist[MAXSTATS])
  193.         Quit ("Too many static objects!\n");
  194. }
  195.  
  196.  
  197. /*
  198. ===============
  199. =
  200. = PlaceItemType
  201. =
  202. = Called during game play to drop actors' items.  It finds the proper
  203. = item number based on the item type (bo_???).  If there are no free item
  204. = spots, nothing is done.
  205. =
  206. ===============
  207. */
  208.  
  209. void PlaceItemType (int itemtype, int tilex, int tiley)
  210. {
  211.     int type;
  212.     statobj_t *spot;
  213.  
  214.     //
  215.     // find the item number
  216.     //
  217.     for (type=0; ; type++)
  218.     {
  219.         if (statinfo[type].picnum == -1)                    // end of list
  220.             Quit ("PlaceItemType: couldn't find type!");
  221.         if (statinfo[type].type == itemtype)
  222.             break;
  223.     }
  224.  
  225.     //
  226.     // find a spot in statobjlist to put it in
  227.     //
  228.     for (spot=&statobjlist[0]; ; spot++)
  229.     {
  230.         if (spot==laststatobj)
  231.         {
  232.             if (spot == &statobjlist[MAXSTATS])
  233.                 return;                                     // no free spots
  234.             laststatobj++;                                  // space at end
  235.             break;
  236.         }
  237.  
  238.         if (spot->shapenum == -1)                           // -1 is a free spot
  239.             break;
  240.     }
  241.     //
  242.     // place it
  243.     //
  244.     spot->shapenum = statinfo[type].picnum;
  245.     spot->tilex = tilex;
  246.     spot->tiley = tiley;
  247.     spot->visspot = &spotvis[tilex][tiley];
  248.     spot->flags = FL_BONUS | statinfo[type].specialFlags;
  249.     spot->itemnumber = statinfo[type].type;
  250. }
  251.  
  252.  
  253.  
  254. /*
  255. =============================================================================
  256.  
  257.                                   DOORS
  258.  
  259. doorobjlist[] holds most of the information for the doors
  260.  
  261. doorposition[] holds the amount the door is open, ranging from 0 to 0xffff
  262.         this is directly accessed by AsmRefresh during rendering
  263.  
  264. The number of doors is limited to 64 because a spot in tilemap holds the
  265.         door number in the low 6 bits, with the high bit meaning a door center
  266.         and bit 6 meaning a door side tile
  267.  
  268. Open doors conect two areas, so sounds will travel between them and sight
  269.         will be checked when the player is in a connected area.
  270.  
  271. Areaconnect is incremented/decremented by each door. If >0 they connect
  272.  
  273. Every time a door opens or closes the areabyplayer matrix gets recalculated.
  274.         An area is true if it connects with the player's current spor.
  275.  
  276. =============================================================================
  277. */
  278.  
  279. #define DOORWIDTH       0x7800
  280. #define OPENTICS        300
  281.  
  282. doorobj_t       doorobjlist[MAXDOORS],*lastdoorobj;
  283. short           doornum;
  284.  
  285. word            doorposition[MAXDOORS];             // leading edge of door 0=closed
  286.                                                     // 0xffff = fully open
  287.  
  288. byte            areaconnect[NUMAREAS][NUMAREAS];
  289.  
  290. boolean         areabyplayer[NUMAREAS];
  291.  
  292.  
  293. /*
  294. ==============
  295. =
  296. = ConnectAreas
  297. =
  298. = Scans outward from playerarea, marking all connected areas
  299. =
  300. ==============
  301. */
  302.  
  303. void RecursiveConnect (int areanumber)
  304. {
  305.     int i;
  306.  
  307.     for (i=0;i<NUMAREAS;i++)
  308.     {
  309.         if (areaconnect[areanumber][i] && !areabyplayer[i])
  310.         {
  311.             areabyplayer[i] = true;
  312.             RecursiveConnect (i);
  313.         }
  314.     }
  315. }
  316.  
  317.  
  318. void ConnectAreas (void)
  319. {
  320.     memset (areabyplayer,0,sizeof(areabyplayer));
  321.     areabyplayer[player->areanumber] = true;
  322.     RecursiveConnect (player->areanumber);
  323. }
  324.  
  325.  
  326. void InitAreas (void)
  327. {
  328.     memset (areabyplayer,0,sizeof(areabyplayer));
  329.     if (player->areanumber < NUMAREAS)
  330.         areabyplayer[player->areanumber] = true;
  331. }
  332.  
  333.  
  334.  
  335. /*
  336. ===============
  337. =
  338. = InitDoorList
  339. =
  340. ===============
  341. */
  342.  
  343. void InitDoorList (void)
  344. {
  345.     memset (areabyplayer,0,sizeof(areabyplayer));
  346.     memset (areaconnect,0,sizeof(areaconnect));
  347.  
  348.     lastdoorobj = &doorobjlist[0];
  349.     doornum = 0;
  350. }
  351.  
  352.  
  353. /*
  354. ===============
  355. =
  356. = SpawnDoor
  357. =
  358. ===============
  359. */
  360.  
  361. void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
  362. {
  363.     word *map;
  364.  
  365.     if (doornum==MAXDOORS)
  366.         Quit ("64+ doors on level!");
  367.  
  368.     doorposition[doornum] = 0;              // doors start out fully closed
  369.     lastdoorobj->tilex = tilex;
  370.     lastdoorobj->tiley = tiley;
  371.     lastdoorobj->vertical = vertical;
  372.     lastdoorobj->lock = lock;
  373.     lastdoorobj->action = dr_closed;
  374.  
  375.     actorat[tilex][tiley] = (objtype *)(uintptr_t)(doornum | 0x80);   // consider it a solid wall
  376.  
  377.     //
  378.     // make the door tile a special tile, and mark the adjacent tiles
  379.     // for door sides
  380.     //
  381.     tilemap[tilex][tiley] = doornum | 0x80;
  382.     map = mapsegs[0] + (tiley<<mapshift) +tilex;
  383.     if (vertical)
  384.     {
  385.         *map = *(map-1);                        // set area number
  386.         tilemap[tilex][tiley-1] |= 0x40;
  387.         tilemap[tilex][tiley+1] |= 0x40;
  388.     }
  389.     else
  390.     {
  391.         *map = *(map-mapwidth);                                 // set area number
  392.         tilemap[tilex-1][tiley] |= 0x40;
  393.         tilemap[tilex+1][tiley] |= 0x40;
  394.     }
  395.  
  396.     doornum++;
  397.     lastdoorobj++;
  398. }
  399.  
  400. //===========================================================================
  401.  
  402. /*
  403. =====================
  404. =
  405. = OpenDoor
  406. =
  407. =====================
  408. */
  409.  
  410. void OpenDoor (int door)
  411. {
  412.     if (doorobjlist[door].action == dr_open)
  413.         doorobjlist[door].ticcount = 0;         // reset open time
  414.     else
  415.         doorobjlist[door].action = dr_opening;  // start it opening
  416. }
  417.  
  418.  
  419. /*
  420. =====================
  421. =
  422. = CloseDoor
  423. =
  424. =====================
  425. */
  426.  
  427. void CloseDoor (int door)
  428. {
  429.     int     tilex,tiley,area;
  430.     objtype *check;
  431.  
  432.     //
  433.     // don't close on anything solid
  434.     //
  435.     tilex = doorobjlist[door].tilex;
  436.     tiley = doorobjlist[door].tiley;
  437.  
  438.     if (actorat[tilex][tiley])
  439.         return;
  440.  
  441.     if (player->tilex == tilex && player->tiley == tiley)
  442.         return;
  443.  
  444.     if (doorobjlist[door].vertical)
  445.     {
  446.         if ( player->tiley == tiley )
  447.         {
  448.             if ( ((player->x+MINDIST) >>TILESHIFT) == tilex )
  449.                 return;
  450.             if ( ((player->x-MINDIST) >>TILESHIFT) == tilex )
  451.                 return;
  452.         }
  453.         check = actorat[tilex-1][tiley];
  454.         if (ISPOINTER(check) && ((check->x+MINDIST) >> TILESHIFT) == tilex )
  455.             return;
  456.         check = actorat[tilex+1][tiley];
  457.         if (ISPOINTER(check) && ((check->x-MINDIST) >> TILESHIFT) == tilex )
  458.             return;
  459.     }
  460.     else if (!doorobjlist[door].vertical)
  461.     {
  462.         if (player->tilex == tilex)
  463.         {
  464.             if ( ((player->y+MINDIST) >>TILESHIFT) == tiley )
  465.                 return;
  466.             if ( ((player->y-MINDIST) >>TILESHIFT) == tiley )
  467.                 return;
  468.         }
  469.         check = actorat[tilex][tiley-1];
  470.         if (ISPOINTER(check) && ((check->y+MINDIST) >> TILESHIFT) == tiley )
  471.             return;
  472.         check = actorat[tilex][tiley+1];
  473.         if (ISPOINTER(check) && ((check->y-MINDIST) >> TILESHIFT) == tiley )
  474.             return;
  475.     }
  476.  
  477.  
  478.     //
  479.     // play door sound if in a connected area
  480.     //
  481.     area = *(mapsegs[0] + (doorobjlist[door].tiley<<mapshift)
  482.         +doorobjlist[door].tilex)-AREATILE;
  483.     if (areabyplayer[area])
  484.     {
  485.         PlaySoundLocTile(CLOSEDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley); // JAB
  486.     }
  487.  
  488.     doorobjlist[door].action = dr_closing;
  489.     //
  490.     // make the door space solid
  491.     //
  492.     actorat[tilex][tiley] = (objtype *)(uintptr_t)(door | 0x80);
  493. }
  494.  
  495.  
  496.  
  497. /*
  498. =====================
  499. =
  500. = OperateDoor
  501. =
  502. = The player wants to change the door's direction
  503. =
  504. =====================
  505. */
  506.  
  507. void OperateDoor (int door)
  508. {
  509.     int lock;
  510.  
  511.     lock = doorobjlist[door].lock;
  512.     if (lock >= dr_lock1 && lock <= dr_lock4)
  513.     {
  514.         if ( ! (gamestate.keys & (1 << (lock-dr_lock1) ) ) )
  515.         {
  516.             SD_PlaySound (NOWAYSND);                // locked
  517.             return;
  518.         }
  519.     }
  520.  
  521.     switch (doorobjlist[door].action)
  522.     {
  523.         case dr_closed:
  524.         case dr_closing:
  525.             OpenDoor (door);
  526.             break;
  527.         case dr_open:
  528.         case dr_opening:
  529.             CloseDoor (door);
  530.             break;
  531.     }
  532. }
  533.  
  534.  
  535. //===========================================================================
  536.  
  537. /*
  538. ===============
  539. =
  540. = DoorOpen
  541. =
  542. = Close the door after three seconds
  543. =
  544. ===============
  545. */
  546.  
  547. void DoorOpen (int door)
  548. {
  549.     if ( (doorobjlist[door].ticcount += (short) tics) >= OPENTICS)
  550.         CloseDoor (door);
  551. }
  552.  
  553.  
  554.  
  555. /*
  556. ===============
  557. =
  558. = DoorOpening
  559. =
  560. ===============
  561. */
  562.  
  563. void DoorOpening (int door)
  564. {
  565.     unsigned area1,area2;
  566.     word *map;
  567.     int32_t position;
  568.  
  569.     position = doorposition[door];
  570.     if (!position)
  571.     {
  572.         //
  573.         // door is just starting to open, so connect the areas
  574.         //
  575.         map = mapsegs[0] + (doorobjlist[door].tiley<<mapshift)
  576.             +doorobjlist[door].tilex;
  577.  
  578.         if (doorobjlist[door].vertical)
  579.         {
  580.             area1 = *(map+1);
  581.             area2 = *(map-1);
  582.         }
  583.         else
  584.         {
  585.             area1 = *(map-mapwidth);
  586.             area2 = *(map+mapwidth);
  587.         }
  588.         area1 -= AREATILE;
  589.         area2 -= AREATILE;
  590.  
  591.         if (area1 < NUMAREAS && area2 < NUMAREAS)
  592.         {
  593.             areaconnect[area1][area2]++;
  594.             areaconnect[area2][area1]++;
  595.  
  596.             if (player->areanumber < NUMAREAS)
  597.                 ConnectAreas ();
  598.  
  599.             if (areabyplayer[area1])
  600.                 PlaySoundLocTile(OPENDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley);  // JAB
  601.         }
  602.     }
  603.  
  604.     //
  605.     // slide the door by an adaptive amount
  606.     //
  607.     position += tics<<10;
  608.     if (position >= 0xffff)
  609.     {
  610.         //
  611.         // door is all the way open
  612.         //
  613.         position = 0xffff;
  614.         doorobjlist[door].ticcount = 0;
  615.         doorobjlist[door].action = dr_open;
  616.         actorat[doorobjlist[door].tilex][doorobjlist[door].tiley] = 0;
  617.     }
  618.  
  619.     doorposition[door] = (word) position;
  620. }
  621.  
  622.  
  623. /*
  624. ===============
  625. =
  626. = DoorClosing
  627. =
  628. ===============
  629. */
  630.  
  631. void DoorClosing (int door)
  632. {
  633.     unsigned area1,area2;
  634.     word *map;
  635.     int32_t position;
  636.     int tilex,tiley;
  637.  
  638.     tilex = doorobjlist[door].tilex;
  639.     tiley = doorobjlist[door].tiley;
  640.  
  641.     if ( ((int)(uintptr_t)actorat[tilex][tiley] != (door | 0x80))
  642.         || (player->tilex == tilex && player->tiley == tiley) )
  643.     {                       // something got inside the door
  644.         OpenDoor (door);
  645.         return;
  646.     };
  647.  
  648.     position = doorposition[door];
  649.  
  650.     //
  651.     // slide the door by an adaptive amount
  652.     //
  653.     position -= tics<<10;
  654.     if (position <= 0)
  655.     {
  656.         //
  657.         // door is closed all the way, so disconnect the areas
  658.         //
  659.         position = 0;
  660.  
  661.         doorobjlist[door].action = dr_closed;
  662.  
  663.         map = mapsegs[0] + (doorobjlist[door].tiley<<mapshift) + doorobjlist[door].tilex;
  664.  
  665.         if (doorobjlist[door].vertical)
  666.         {
  667.             area1 = *(map+1);
  668.             area2 = *(map-1);
  669.         }
  670.         else
  671.         {
  672.             area1 = *(map-mapwidth);
  673.             area2 = *(map+mapwidth);
  674.         }
  675.         area1 -= AREATILE;
  676.         area2 -= AREATILE;
  677.  
  678.         if (area1 < NUMAREAS && area2 < NUMAREAS)
  679.         {
  680.             areaconnect[area1][area2]--;
  681.             areaconnect[area2][area1]--;
  682.  
  683.             if (player->areanumber < NUMAREAS)
  684.                 ConnectAreas ();
  685.         }
  686.     }
  687.  
  688.     doorposition[door] = (word) position;
  689. }
  690.  
  691.  
  692.  
  693.  
  694. /*
  695. =====================
  696. =
  697. = MoveDoors
  698. =
  699. = Called from PlayLoop
  700. =
  701. =====================
  702. */
  703.  
  704. void MoveDoors (void)
  705. {
  706.     int door;
  707.  
  708.     if (gamestate.victoryflag)              // don't move door during victory sequence
  709.         return;
  710.  
  711.     for (door = 0; door < doornum; door++)
  712.     {
  713.         switch (doorobjlist[door].action)
  714.         {
  715.             case dr_open:
  716.                 DoorOpen (door);
  717.                 break;
  718.  
  719.             case dr_opening:
  720.                 DoorOpening(door);
  721.                 break;
  722.  
  723.             case dr_closing:
  724.                 DoorClosing(door);
  725.                 break;
  726.         }
  727.     }
  728. }
  729.  
  730.  
  731. /*
  732. =============================================================================
  733.  
  734.                                 PUSHABLE WALLS
  735.  
  736. =============================================================================
  737. */
  738.  
  739. word pwallstate;
  740. word pwallpos;                  // amount a pushable wall has been moved (0-63)
  741. word pwallx,pwally;
  742. byte pwalldir,pwalltile;
  743. int dirs[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
  744.  
  745. /*
  746. ===============
  747. =
  748. = PushWall
  749. =
  750. ===============
  751. */
  752.  
  753. void PushWall (int checkx, int checky, int dir)
  754. {
  755.     int oldtile, dx, dy;
  756.  
  757.     if (pwallstate)
  758.         return;
  759.  
  760.     oldtile = tilemap[checkx][checky];
  761.     if (!oldtile)
  762.         return;
  763.  
  764.     dx = dirs[dir][0];
  765.     dy = dirs[dir][1];
  766.  
  767.     if (actorat[checkx+dx][checky+dy])
  768.     {
  769.         SD_PlaySound (NOWAYSND);
  770.         return;
  771.     }
  772.     actorat[checkx+dx][checky+dy] = (objtype *)(uintptr_t) (tilemap[checkx+dx][checky+dy] = oldtile);
  773.  
  774.     gamestate.secretcount++;
  775.     pwallx = checkx;
  776.     pwally = checky;
  777.     pwalldir = dir;
  778.     pwallstate = 1;
  779.     pwallpos = 0;
  780.     pwalltile = tilemap[pwallx][pwally];
  781.     tilemap[pwallx][pwally] = 64;
  782.     tilemap[pwallx+dx][pwally+dy] = 64;
  783.     *(mapsegs[1]+(pwally<<mapshift)+pwallx) = 0;   // remove P tile info
  784.     *(mapsegs[0]+(pwally<<mapshift)+pwallx) = *(mapsegs[0]+(player->tiley<<mapshift)+player->tilex); // set correct floorcode (BrotherTank's fix)
  785.  
  786.     SD_PlaySound (PUSHWALLSND);
  787. }
  788.  
  789.  
  790.  
  791. /*
  792. =================
  793. =
  794. = MovePWalls
  795. =
  796. =================
  797. */
  798.  
  799. void MovePWalls (void)
  800. {
  801.     int oldblock,oldtile;
  802.  
  803.     if (!pwallstate)
  804.         return;
  805.  
  806.     oldblock = pwallstate/128;
  807.  
  808.     pwallstate += (word)tics;
  809.  
  810.     if (pwallstate/128 != oldblock)
  811.     {
  812.         // block crossed into a new block
  813.         oldtile = pwalltile;
  814.  
  815.         //
  816.         // the tile can now be walked into
  817.         //
  818.         tilemap[pwallx][pwally] = 0;
  819.         actorat[pwallx][pwally] = 0;
  820.         *(mapsegs[0]+(pwally<<mapshift)+pwallx) = player->areanumber+AREATILE;
  821.  
  822.         int dx=dirs[pwalldir][0], dy=dirs[pwalldir][1];
  823.         //
  824.         // see if it should be pushed farther
  825.         //
  826.         if (pwallstate>=256)            // only move two tiles fix
  827.         {
  828.             //
  829.             // the block has been pushed two tiles
  830.             //
  831.             pwallstate = 0;
  832.             tilemap[pwallx+dx][pwally+dy] = oldtile;
  833.             return;
  834.         }
  835.         else
  836.         {
  837.             int xl,yl,xh,yh;
  838.             xl = (player->x-PLAYERSIZE) >> TILESHIFT;
  839.             yl = (player->y-PLAYERSIZE) >> TILESHIFT;
  840.             xh = (player->x+PLAYERSIZE) >> TILESHIFT;
  841.             yh = (player->y+PLAYERSIZE) >> TILESHIFT;
  842.  
  843.             pwallx += dx;
  844.             pwally += dy;
  845.  
  846.             if (actorat[pwallx+dx][pwally+dy]
  847.                 || xl<=pwallx+dx && pwallx+dx<=xh && yl<=pwally+dy && pwally+dy<=yh)
  848.             {
  849.                 pwallstate = 0;
  850.                 tilemap[pwallx][pwally] = oldtile;
  851.                 return;
  852.             }
  853.             actorat[pwallx+dx][pwally+dy] = (objtype *)(uintptr_t) (tilemap[pwallx+dx][pwally+dy] = oldtile);
  854.             tilemap[pwallx+dx][pwally+dy] = 64;
  855.         }
  856.     }
  857.  
  858.     pwallpos = (pwallstate/2)&63;
  859. }
  860.