home *** CD-ROM | disk | FTP | other *** search
- // ------------ shootout.cpp
-
- #include <stdlib.h>
- #include "shootout.h"
- #include "options.h"
-
- Portal Shootout::portals[] = {
- { nobldg, 0, 0, 0, 0, 1}, // nowhere
- { house, 27, 63, 41, 77, 0}, // window1
- { house, 52, 63, 66, 77, 0}, // window2
- { house, 78, 63, 91, 77, 0}, // window3
- { house, 27, 117, 41, 131, 0}, // window4
- { house, 78, 117, 91, 131, 0}, // window5
- { house, 61, 0, 319, 239, 0}, // housedoor
- { nobldg, 102, 0, 118, 239, 0}, // alley1
- { jail, 183, 0, 319, 239, 0}, // jaildoor
- { nobldg, 216, 0, 233, 239, 0}, // alley2
- { saloon, 260, 0, 319, 239, 0}, // saloondoor
- { saloon, 244, 56, 258, 69, 0}, // window6
- { saloon, 268, 56, 282, 69, 0}, // window7
- { saloon, 291, 56, 305, 69, 0} // window8
- };
-
- static Location houseentr[] = {
- window1, window2, window3, window4, window5, housedoor, alley2
- };
- static Location jailentr[] = { alley2, jaildoor, alley3 };
- static Location saloonentr[] = {
- alley3, saloondoor, window6, window7, window8
- };
- Location *Shootout::entrances[] = { 0, houseentr, jailentr, saloonentr };
- int Shootout::entrcounts[] = { 0, 7, 3, 5 };
-
- Building nextbldg[][2] = {
- { nobldg, nobldg }, // nowhere
- { house, house }, // window1
- { house, house }, // window2
- { house, house }, // window3
- { house, house }, // window4
- { house, house }, // window5
- { house, house }, // housedoor
- { jail, house }, // alley2
- { jail, jail }, // jaildoor
- { saloon, jail }, // alley3
- { saloon, saloon }, // saloondoor
- { saloon, saloon }, // window6
- { saloon, saloon }, // window7
- { saloon, saloon } // window8
- };
-
- Shootout::Shootout() : SceneDirector("town.pcx", fade)
- {
- bullets = new Digit;
- citizens = new Digit;
- badguys = new Digit;
- actorctr = 0;
- conductor = new MusicHand("shootout.xmi");
- door3 = new Door(3);
- door2 = new Door(2);
- door1 = new Door(1);
- actors[actorctr++] = new Sadie;
- actors[actorctr++] = new Deputy;
- actors[actorctr++] = new Parson;
- actors[actorctr++] = new BadSadie;
- actors[actorctr++] = new BadDeputy;
- actors[actorctr++] = new BadParson;
- sheriff = new Sheriff;
- finalscreen = new Player("finalscr.gfx", "sounds.sfx");
- }
-
- Shootout::~Shootout()
- {
- for (int i = 0; i < actorctr; i++) {
- delete actors[i];
- actors[i] = 0;
- actorctr = 0;
- }
- delete conductor;
- }
- void Shootout::display()
- {
- sheriff->initialize_sheriff();
- SceneDirector::display();
- for (int i = 1; i < 14; i++)
- portals[i].occupied = 0;
- randomize();
- rinterval = random(maxticks);
- rticks = 0;
- screenshattered = 0;
- certificate = 0;
- badguysintown = 0;
- door1->initialize_door();
- door2->initialize_door();
- door3->initialize_door();
- sheriff->appear();
- distribute_players();
- conductor->play_music_clip(1);
- bullets->setxy(59,215);
- bullets->appear();
- citizens->setxy(176,215);
- citizens->setnum(0);
- citizens->appear();
- badguys->setxy(300,215);
- badguys->setnum(0);
- badguys->appear();
- }
- void Shootout::hide()
- {
- conductor->stop_music_clip();
- sheriff->disappear();
- finalscreen->disappear();
- SceneDirector::hide();
- }
- // ---- initially distribute the players evenly among the buildings
- void Shootout::distribute_players()
- {
- short int *ply = new short int[actorctr];
- for (int i = 0; i < actorctr; i++)
- *(ply+i) = 0;
- Building bldg = nobldg;
- for (short int acs = 0; acs < actorctr; acs++) {
- actors[acs]->initialize_bitpart();
- if ((acs&1) == 0)
- bldg++;
- short int ac;
- do
- ac = random(actorctr);
- while (ply[ac] != 0);
- ply[ac] = 1;
- actors[ac]->clipper.building = bldg;
- }
- delete ply;
- }
-
- BitPart *Shootout::select_actor()
- {
- int maxbadguys = options->fletchers->getnum();
- // --- first see if there are any invisible actors
- // (they might all be on stage)
- for (int pl = 0; pl < actorctr; pl++) {
- if ((actors[pl]->isvisible()))
- continue;
- if (!actors[pl]->iscitizen())
- // --- a bad guy
- if (badguysintown == maxbadguys)
- continue;
- break;
- }
- if (pl == actorctr)
- return 0;
- // --- choose an available (invisible) player at random
- for (;;) {
- pl = random(actorctr);
- if ((actors[pl]->isvisible()))
- continue;
- if (!actors[pl]->iscitizen())
- // --- a bad guy
- if (badguysintown == maxbadguys)
- continue;
- break;
- }
- return actors[pl];
- }
-
- int Shootout::entrance_available(Location loc)
- {
- return (
- portals[loc].occupied == 0 &&
- (!sheriff->isdead() || on_the_street(loc)) );
- }
-
- Location Shootout::select_location(BitPart *bp)
- {
- Building currbldg = bp->clipper.building;
- int ecnt = entrcounts[currbldg];
- Location *locp = entrances[currbldg];
- Location loc;
-
- // --- first see if there are any unoccupied, eliglible entrances
- for (int locoffset = 0; locoffset < ecnt; locoffset++) {
- loc = locp[locoffset];
- if (entrance_available(loc))
- break;
- }
- if (locoffset == ecnt)
- return nowhere;
- // --- there is at least one entrance available, pick one at random
- do
- loc = locp[random(ecnt)];
- while (!entrance_available(loc));
- return loc;
- }
-
- void Shootout::on_timer()
- {
- if (!conductor->music_clip_is_playing())
- conductor->play_music_clip(1);
- if (screenshattered) {
- if (screenshattered == 1) {
- while (finalscreen->sound_clip_is_playing())
- ;
- screenshattered = 2;
- finalscreen->set_imageno(3);
- finalscreen->setxy(60,65);
- finalscreen->appear();
- finalscreen->play_sound_clip(9);
- }
- SceneDirector::on_timer();
- return;
- }
- if (certificate) {
- if (certificate != 3) {
- // ---- display a death certificate
- finalscreen->set_imageno(certificate);
- finalscreen->setxy(60,65);
- finalscreen->appear();
- certificate = 3;
- SceneDirector::on_timer();
- }
- return;
- }
- SceneDirector::on_timer();
- int sheriffdead = sheriff->isdead();
- int badguysdead = badguys->getnum() == 3;
- if (sheriffdead || badguysdead || rticks++ == rinterval) {
- rticks = 0;
- // ---- time to send in a bit player
- BitPart *bp = select_actor();
- if (bp != 0) {
- // --- found an off-stage player, pick an entrance
- // based on the building where the player is now
- Location loc = select_location(bp);
- if (loc != nowhere)
- enteractor(bp, loc);
- }
- rinterval = random(maxticks);
- }
- }
-
- void Shootout::enteractor(BitPart *bp, Location loc)
- {
- int sheriffdead = sheriff->isdead();
- short int badguysdead = badguys->getnum() == 3;
- short int citizendead = citizens->getnum();
- // ---- if 1 sheriff or 3 badguys are dead, go to the street only
- if ((sheriffdead || badguysdead) && !on_the_street(loc))
- return;
- // ---- if 3 badguys are dead and any citizens, don't enter
- if (badguysdead && citizendead)
- return;
- // ---- bad guys stay off the street after the sheriff is dead
- if (!bp->iscitizen() && sheriffdead)
- return;
- Door *dor = 0;
- switch (loc) {
- case housedoor:
- dor = door1;
- break;
- case jaildoor:
- dor = door2;
- break;
- case saloondoor:
- dor = door3;
- break;
- default:
- break;
- }
- // --- clip the actor's display to the entranceway
- bp->clip(portals[loc].x1, portals[loc].y1,
- portals[loc].x2, portals[loc].y2);
- // --- mark the door/alley as occupied
- portals[loc].occupied = 1;
- // --- count the number of bad guys on the street
- if (!bp->iscitizen())
- badguysintown++;
- // --- tell the actor to make an entrance
- bp->enter(portals[loc], dor, loc);
- }
- // --- find the actors in zone
- short int Shootout::findactors(BitPart *actrs[], short int zone)
- {
- short int ct = 0;
- for (int pl = 0; pl < actorctr; pl++)
- if (actors[pl]->zone() == zone)
- actrs[ct++] = actors[pl];
- return ct;
- }
- // --- find the actors in zone1 and zone2
- short int Shootout::findactors(BitPart *actrs[],
- short int zone1, short int zone2)
- {
- short int ct = findactors(actrs, zone1);
- if (zone1 != zone2 && zone2 != 0)
- ct += findactors(actrs+ct, zone2);
- return ct;
- }
- // ---- test if anyone other than caller is drawing down on sheriff
- short int Shootout::isbadguy_shooting(BitPart *bp)
- {
- for (int pl = 0; pl < actorctr; pl++)
- if (actors[pl] != bp)
- if (actors[pl]->isshooting())
- return 1;
- return 0;
- }
- // ---- an actor is leaving the stage
- void Shootout::exitstage(BitPart *bp)
- {
- // ---- free the entrance position for another actor to use
- portals[bp->location].occupied = 0;
- // ---- update actor's position based on
- // current location and direction of exit
- bp->clipper.building = nextbldg[bp->location][bp->exitright];
- if (!bp->iscitizen())
- --badguysintown;
- }
-
-