home *** CD-ROM | disk | FTP | other *** search
- // ------------ sheriff.cpp
-
- #include "shootout.h"
- #include "options.h"
-
- CUELIST(Sheriff)
- KEYSTROKE(UP, OnShoot)
- KEYSTROKE(DN, OnShoot)
- KEYSTROKE(PGUP, OnShoot)
- KEYSTROKE(HOME, OnShoot)
- KEYSTROKE(RT, OnChangeDirection)
- KEYSTROKE(LF, OnChangeDirection)
- KEYSTROKE('r', OnReload)
- KEYSTROKE('x', OnResurrection)
- ENDCUELIST
-
- const short int FirstX = 15;
- const short int FirstY = 120;
- // --- step increments of the sheriff's stroll
- short int Sheriff::walkincr[] = { 5,7,6,7 };
- // ---- frame imageno array for the 4 shoot sequences
- short int Sheriff::shoot[4][5] = {
- {11,12,13,12,27},
- {14,15,16,15,14},
- {17,18,19,18,17},
- {20,21,22,21,20}
- };
-
- const int walkinterval = 2;
- const int shootinterval = 2;
-
- Sheriff::Sheriff() : Player("sheriff.gfx", "sounds.sfx", walkinterval)
- {
- }
-
- void Sheriff::initialize_sheriff()
- {
- frame = 0;
- incr = 1;
- setx(FirstX);
- sety(FirstY);
- of = 0;
- offset = 0;
- steps = 0;
- forward = 1;
- mode = walk;
- shootseq = 0;
- bullets = 6;
- ((Shootout*)director)->bullets->setnum(bullets);
- deadx = 0;
- resurrections = 0;
- setinterval(walkinterval);
- disappear();
- }
- void Sheriff::OnResurrection(int)
- {
- if (mode == dead)
- mode = resurrecting;
- }
- // ----- keyboard shoot command callback function
- void Sheriff::OnShoot(int key)
- {
- if (!isdead() && mode != falling) {
- setinterval(shootinterval);
- switch (key) {
- case UP:
- mode = rear;
- break;
- case DN:
- mode = front;
- break;
- case PGUP:
- mode = right;
- break;
- case HOME:
- mode = left;
- break;
- default:
- break;
- }
- }
- }
- // ---- the frame animation entry point from Theatrix
- void Sheriff::update_position()
- {
- int y;
- switch (mode) {
- case walk:
- Walk();
- break;
- case dying:
- // ----- sheriff got shot
- set_imageno(forward ? 23 : 24);
- deadx = getx();
- if (deadx > 240)
- setx(240);
- mode = falling;
- case falling:
- setinterval(1);
- y = gety();
- if (y < sidewalk+20)
- sety(y+10);
- else
- mode = dead;
- break;
- case dead:
- // ---- sheriff got killed
- break;
- case resurrecting:
- if (((Shootout*)director)->parsonisdead()) {
- // --- can't be resurrected if you kill the parson
- ((Shootout*)director)->deathcertificate(1);
- mode = dead;
- }
- else if (resurrections < options->resurrections->getnum()) {
- mode = resurrected;
- resurrections++;
- }
- else {
- ((Shootout*)director)->deathcertificate(2);
- mode = dead;
- }
- break;
- case resurrected:
- bullets = 6;
- ((Shootout*)director)->bullets->setnum(bullets);
- set_imageno(frame+offset);
- sety(FirstY);
- setx(deadx);
- mode = walk;
- break;
- case reload:
- Reload();
- break;
- default:
- Shoot(mode);
- break;
- }
- }
- // ---- reloading
- void Sheriff::Reload()
- {
- short int im = get_imageno();
- switch (im) {
- case 11:
- set_imageno(25);
- break;
- case 25:
- set_imageno(26);
- break;
- case 26:
- if (bullets == 6) {
- mode = walk;
- set_imageno(11);
- break;
- }
- set_imageno(25);
- bullets++;
- ((Shootout*)director)->bullets->setnum(bullets);
- break;
- default:
- break;
- }
- }
- // ---- point sheriff in the opposite direction
- void Sheriff::OnChangeDirection(int ky)
- {
- if (forward && ky == RT)
- return;
- if (!forward && ky == LF)
- return;
- forward ^= 1;
- steps = 39-steps;
- offset = 5-offset;
- }
- // ---- play a frame of the sheriff's walk animation sequence
- void Sheriff::Walk()
- {
- setinterval(walkinterval);
- if (++steps == 40) {
- steps = 0;
- forward ^= 1;
- incr = 1;
- of = 0;
- frame = 0;
- if (forward) {
- offset = 0;
- setx(FirstX);
- }
- else
- offset = 5;
- }
- else {
- if (forward)
- setx(getx() + walkincr[of]);
- else
- setx(getx() - walkincr[of]);
- if (++of == 4)
- of = 0;
- }
- frame += incr;
- if (frame == 5)
- incr = -1;
- else if (frame == 1)
- incr = 1;
- set_imageno(frame+offset);
- }
- // --- compute target zone from position and direction of shot
- void Sheriff::targetzone(short int& zone1, short int& zone2)
- {
- short int tzone = zone();
- zone1 = zone2 = 0;
- if (mode == right) {
- if (tzone != 5) {
- zone1 = tzone+1;
- if (zone1 != 5)
- zone2 = zone1+1;
- }
- return;
- }
- if (mode == left) {
- if (tzone != 1) {
- zone1 = tzone-1;
- if (zone1 != 1)
- zone2 = zone1-1;
- }
- return;
- }
- if (mode == rear)
- zone1 = tzone;
- }
- // ---- find a target for the latest shot
- BitPart *Sheriff::findtarget()
- {
- BitPart *acs[maxactors];
- BitPart *bp = 0;
- short int zone1, zone2;
- targetzone(zone1, zone2);
- if (zone1) {
- int ct = ((Shootout*)director)->findactors(acs, zone1, zone2);
- for (int i = 0; i < ct; i++) {
- if (bp == 0 || !acs[i]->iscitizen())
- bp = acs[i];
- if (!acs[i]->iscitizen())
- break;
- }
- }
- return bp;
- }
- // ---- fire a shot
- inline void Sheriff::fire()
- {
- if (bullets > 0) {
- play_sound_clip(1);
- --bullets;
- ((Shootout*)director)->bullets->setnum(bullets);
- if (mode == front)
- ((Shootout*)director)->shatterscreen();
- else {
- BitPart *trg = findtarget();
- if (trg != 0) {
- if (trg->iscitizen())
- (*((Shootout*)director)->citizens)++;
- else
- (*((Shootout*)director)->badguys)++;
- trg->getshot();
- }
- }
- }
- else
- play_sound_clip(2);
- }
- // ---- play a frame of the sheriff's shoot animation sequence
- void Sheriff::Shoot(Mode md)
- {
- short int shame = (mode == front && bullets > 0);
- if (bullets > 0 || shootseq != 2)
- set_imageno(shoot[md][shootseq]);
- if (shootseq == 2) // the firing frame
- fire();
- if (shootseq == 3 && mode == front)
- setinterval(10);
- if (++shootseq == 5) {
- // --- last frame in the sequence
- mode = shame ? dead : walk;
- shootseq = 0;
- }
- }
- // ---- compute zone (1/5 of the walk) 1 to 5 that the sheriff is in
- short int Sheriff::zone()
- {
- short int zn = steps/8+1;
- if (!forward)
- zn = (5 - zn) + 1;
- return zn;
- }
-
- // ------ called to kill the sheriff
- void Sheriff::getshot()
- {
- mode = dying;
- }
-
- // ----- reload the gun
- void Sheriff::OnReload(int)
- {
- if (!isdead() && mode != reload) {
- mode = reload;
- set_imageno(11);
- }
- }
-