/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ /* * This code is based on the original source code of Lord Avalot d'Argent version 1.3. * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman. */ /* TRIP5 Trippancy V */ #include "avalanche/trip6.h" #include "common/scummsys.h" #include "common/textconsole.h" #include "avalanche/scrolls2.h" #include "avalanche/lucerna2.h" #include "avalanche/visa2.h" #include "avalanche/gyro2.h" #include "avalanche/celer2.h" #include "avalanche/sequence2.h" #include "avalanche/timeout2.h" #include "avalanche/enid2.h" /*#include "Dropdown.h"*/ namespace Avalanche { namespace Trip { void loadtrip() { byte gm; for (gm = 1; gm <= numtr; gm ++) tr[gm].original(); for (int i = 0; i < sizeof(aa); aa[i] = 0); } byte checkfeet(int16 x1, int16 x2, int16 oy, int16 y, byte yl) { byte a, c; int16 fv, ff; /* if not alive then begin checkfeet:=0; exit; end;*/ byte checkfeet_result; a = 0; warning("STUB: Trip::checkfeet()"); checkfeet_result = a; return checkfeet_result; } byte geida_ped(byte which) { byte geida_ped_result; switch (which) { case 1: geida_ped_result = 7; break; case 2: case 6: geida_ped_result = 8; break; case 3: case 5: geida_ped_result = 9; break; case 4: geida_ped_result = 10; break; } return geida_ped_result; } void catamove(byte ped) /* When you enter a new position in the catacombs, this procedure should be called. It changes the Also codes so that they may match the picture on the screen. (Coming soon: It draws up the screen, too.) */ { warning("Repair array indexes in Trip::catamove()"); int32 here; uint16 xy_uint16; byte fv, ff; /* XY_uint16 is cat_x+cat_y*256. Thus, every room in the catacombs has a different number for it. */ xy_uint16 = Gyro::dna.cat_x + Gyro::dna.cat_y * 256; Gyro::dna.geida_spin = 0; switch (xy_uint16) { case 1801: { /* Exit catacombs */ fliproom(r__lustiesroom, 4); Scrolls::display("Phew! Nice to be out of there!"); return; } break; case 1033: { /* Oubliette */ fliproom(r__oubliette, 1); Scrolls::display("Oh, NO!\231\2"); return; } break; case 4: { fliproom(r__geidas, 1); return; } break; case 2307: { fliproom(r__lusties, 5); Scrolls::display("Oh no... here we go again..."); Gyro::dna.user_moves_avvy = false; tr[1].iy = 1; tr[1].ix = 0; return; } break; } if (! Gyro::dna.enter_catacombs_from_lusties_room) Lucerna::load(29); here = Gyro::catamap[Gyro::dna.cat_y][Gyro::dna.cat_x]; switch (here & 0xf) { /* West. */ case 0: { /* no connection (wall) */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::nix; /* Door. */ Celer::show_one(28); } break; case 0x1: { /* no connection (wall + shield), */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::nix; /* Door. */ Celer::show_one(28); /* Wall, plus... */ Celer::show_one(29); /* ...shield. */ } break; case 0x2: { /* wall with door */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::special; /* Door. */ Celer::show_one(28); /* Wall, plus... */ Celer::show_one(30); /* ...door. */ } break; case 0x3: { /* wall with door and shield */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::special; /* Door. */ Celer::show_one(28); /* Wall, plus... */ Celer::show_one(30); /* ...door, and... */ Celer::show_one(29); /* ...shield. */ } break; case 0x4: { /* no connection (wall + window), */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::nix; /* Door. */ Celer::show_one(28); /* Wall, plus... */ Celer::show_one(5); /* ...window. */ } break; case 0x5: { /* wall with door and window */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::special; /* Door. */ Celer::show_one(28); /* Wall, plus... */ Celer::show_one(30); /* ...door, and... */ Celer::show_one(5); /* ...window. */ } break; case 0x6: { /* no connection (wall + torches), */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::nix; /* No door. */ Celer::show_one(28); /* Wall, plus... */ Celer::show_one(7); /* ...torches. */ } break; case 0x7: { /* wall with door and torches */ Gyro::magics[2].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[3].op = Gyro::nix; /* Straight wall. */ Gyro::portals[13].op = Gyro::special; /* Door. */ Celer::show_one(28); /* Wall, plus... */ Celer::show_one(30); /* ...door, and... */ Celer::show_one(7); /* ...torches. */ } break; case 0xf: { /* straight-through corridor. */ Gyro::magics[2].op = Gyro::nix; /* Sloping wall. */ Gyro::magics[3].op = Gyro::special; /* Straight wall. */ } break; } /* ---- */ switch ((here & 0xf0) >> 4) { /* East */ case 0: { /* no connection (wall) */ Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ Gyro::portals[15].op = Gyro::nix; /* Door. */ Celer::show_one(19); } break; case 0x1: { /* no connection (wall + window), */ Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ Gyro::portals[15].op = Gyro::nix; /* Door. */ Celer::show_one(19); /* Wall, plus... */ Celer::show_one(20); /* ...window. */ } break; case 0x2: { /* wall with door */ Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ Gyro::portals[15].op = Gyro::special; /* Door. */ Celer::show_one(19); /* Wall, plus... */ Celer::show_one(21); /* ...door. */ } break; case 0x3: { /* wall with door and window */ Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ Gyro::portals[15].op = Gyro::special; /* Door. */ Celer::show_one(19); /* Wall, plus... */ Celer::show_one(20); /* ...door, and... */ Celer::show_one(21); /* ...window. */ } break; case 0x6: { /* no connection (wall + torches), */ Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ Gyro::portals[15].op = Gyro::nix; /* No door. */ Celer::show_one(19); /* Wall, plus... */ Celer::show_one(18); /* ...torches. */ } break; case 0x7: { /* wall with door and torches */ Gyro::magics[5].op = Gyro::bounces; /* Sloping wall. */ Gyro::magics[6].op = Gyro::nix; /* Straight wall. */ Gyro::portals[15].op = Gyro::special; /* Door. */ Celer::show_one(19); /* Wall, plus... */ Celer::show_one(21); /* ...door, and... */ Celer::show_one(18); /* ...torches. */ } break; case 0xf: { /* straight-through corridor. */ Gyro::magics[5].op = Gyro::nix; /* Sloping wall. */ Gyro::magics[6].op = Gyro::special; /* Straight wall. */ Gyro::portals[15].op = Gyro::nix; /* Door. */ } break; } /* ---- */ switch ((here & 0xf00) >> 8) { /* South */ case 0: { /* No connection. */ Gyro::magics[7].op = Gyro::bounces; Gyro::magics[12].op = Gyro::bounces; Gyro::magics[13].op = Gyro::bounces; } break; case 0x1: { Celer::show_one(22); if ((xy_uint16 == 2051) & (Gyro::dna.geida_follows)) Gyro::magics[13].op = Gyro::exclaim; else Gyro::magics[13].op = Gyro::special; /* Right exit south. */ Gyro::magics[7].op = Gyro::bounces; Gyro::magics[12].op = Gyro::bounces; } break; case 0x2: { Celer::show_one(23); Gyro::magics[7].op = Gyro::special; /* Middle exit south. */ Gyro::magics[12].op = Gyro::bounces; Gyro::magics[13].op = Gyro::bounces; } break; case 0x3: { Celer::show_one(24); Gyro::magics[12].op = Gyro::special; /* Left exit south. */ Gyro::magics[7].op = Gyro::bounces; Gyro::magics[13].op = Gyro::bounces; } break; } switch ((here & 0xf000) >> 12) { /* North */ case 0: { /* No connection */ Gyro::magics[1].op = Gyro::bounces; Gyro::portals[12].op = Gyro::nix; /* Door. */ } break; /* LEFT handles: */ /* $1: begin Celer::show_one(4); Gyro::magics[1].op:=Gyro::bounces; { Left exit north. } { Change magic number! } Gyro::portals[12].op:=Gyro::special; { Door. } end;*/ case 0x2: { Celer::show_one(4); Gyro::magics[1].op = Gyro::bounces; /* Middle exit north. */ Gyro::portals[12].op = Gyro::special; /* Door. */ } break; /* $3: begin Celer::show_one(4); Gyro::magics[1].op:=Gyro::bounces; { Right exit north. } { Change magic number! } Gyro::portals[12].op:=Gyro::special; { Door. } end; { RIGHT handles: } $4: begin Celer::show_one(3); Gyro::magics[1].op:=Gyro::bounces; { Left exit north. } { Change magic number! } Gyro::portals[12].op:=Gyro::special; { Door. } end;*/ case 0x5: { Celer::show_one(3); Gyro::magics[1].op = Gyro::bounces; /* Middle exit north. */ Gyro::portals[12].op = Gyro::special; /* Door. */ } break; /* $6: begin Celer::show_one(3); Gyro::magics[1].op:=Gyro::bounces; { Right exit north. } Gyro::portals[12].op:=Gyro::special; { Door. } end;*/ /* ARCHWAYS: */ case 0x7: case 0x8: case 0x9: { Celer::show_one(6); if (((here & 0xf000) >> 12) > 0x7) Celer::show_one(31); if (((here & 0xf000) >> 12) == 0x9) Celer::show_one(32); Gyro::magics[1].op = Gyro::special; /* Middle arch north. */ Gyro::portals[12].op = Gyro::nix; /* Door. */ } break; /* DECORATIONS: */ case 0xd: { /* No connection + WINDOW */ Gyro::magics[1].op = Gyro::bounces; Gyro::portals[12].op = Gyro::nix; /* Door. */ Celer::show_one(14); } break; case 0xe: { /* No connection + TORCH */ Gyro::magics[1].op = Gyro::bounces; Gyro::portals[12].op = Gyro::nix; /* Door. */ Celer::show_one(8); } break; /* Recessed door: */ case 0xf: { Gyro::magics[1].op = Gyro::nix; /* Door to Geida's room. */ Celer::show_one(1); Gyro::portals[12].op = Gyro::special; /* Door. */ } break; } switch (xy_uint16) { case 514: Celer::show_one(17); break; /* [2,2] : "Art Gallery" sign over door. */ case 264: Celer::show_one(9); break; /* [8,1] : "The Wrong Way!" sign. */ case 1797: Celer::show_one(2); break; /* [5,7] : "Ite Mingite" sign. */ case 258: for (fv = 0; fv <= 2; fv ++) { /* [2,1] : Art gallery - pictures */ Celer::show_one_at(15, 130 + fv * 120, 70); Celer::show_one_at(16, 184 + fv * 120, 78); } break; case 1287: for (fv = 10; fv <= 13; fv ++) Celer::show_one(fv); break; /* [7,5] : 4 candles. */ case 776: Celer::show_one(10); break; /* [8,3] : 1 candle. */ case 2049: Celer::show_one(11); break; /* [1,8] : another candle. */ case 257: { Celer::show_one(12); Celer::show_one(13); } break; /* [1,1] : the other two. */ } if ((Gyro::dna.geida_follows) & (ped > 0)) { triptype &with = tr[2]; if (! with.quick) /* If we don't already have her... */ tr[2].init(5, true); /* ...Load Geida. */ apped(2, geida_ped(ped)); tr[2].call_eachstep = true; tr[2].eachstep = procgeida_procs; } } void call_special(uint16 which); /* This proc gets called whenever you touch a line defined as Gyro::special. */ static void dawndelay() { Timeout::set_up_timer(2, Timeout::procdawn_delay, Timeout::reason_dawndelay); } void call_special(uint16 which) { switch (which) { case 1: { /* Gyro::special 1: Room 22: top of stairs. */ Celer::show_one(1); Gyro::dna.brummie_stairs = 1; Gyro::magics[10].op = Gyro::nix; Timeout::set_up_timer(10, Timeout::procstairs, Timeout::reason_brummiestairs); stopwalking(); Gyro::dna.user_moves_avvy = false; } break; case 2: { /* Gyro::special 2: Room 22: bottom of stairs. */ Gyro::dna.brummie_stairs = 3; Gyro::magics[11].op = Gyro::nix; Gyro::magics[12].op = Gyro::exclaim; Gyro::magics[12].data = 5; Gyro::magics[4].op = Gyro::bounces; /* Now works as planned! */ stopwalking(); Visa::dixi('q', 26); Gyro::dna.user_moves_avvy = true; } break; case 3: { /* Gyro::special 3: Room 71: triggers dart. */ tr[1].bounce(); /* Must include that. */ if (! Gyro::dna.arrow_triggered) { Gyro::dna.arrow_triggered = true; apped(2, 4); /* The dart starts at ped 4, and... */ tr[2].walkto(5); /* flies to ped 5. */ tr[2].face = 0; /* Only face. */ /* Should call some kind of Eachstep procedure which will deallocate the sprite when it hits the wall, and replace it with the chunk graphic of the arrow buried in the plaster. */ /* OK! */ tr[2].call_eachstep = true; tr[2].eachstep = procarrow_procs; } } break; case 4: { /* This is the ghost room link. */ Lucerna::dusk(); tr[1].turn(right); /* you'll see this after we get back from bootstrap */ Timeout::set_up_timer(1, Timeout::procghost_room_phew, Timeout::reason_ghost_room_phew); Enid::back_to_bootstrap(3); } break; case 5: if (Gyro::dna.friar_will_tie_you_up) { /* Gyro::special 5: Room 42: touched tree, and get tied up. */ Gyro::magics[4].op = Gyro::bounces; /* Boundary effect is now working again. */ Visa::dixi('q', 35); tr[1].done(); /*tr[1].vanishifstill:=true;*/ Celer::show_one(2); Visa::dixi('q', 36); Gyro::dna.tied_up = true; Gyro::dna.friar_will_tie_you_up = false; tr[2].walkto(3); tr[2].vanishifstill = true; tr[2].check_me = true; /* One of them must have Check_Me switched on. */ Gyro::whereis[Gyro::pfriartuck] = 177; /* Not here, then. */ Timeout::set_up_timer(364, Timeout::prochang_around, Timeout::reason_hanging_around); } break; case 6: { /* Gyro::special 6: fall down oubliette. */ Gyro::dna.user_moves_avvy = false; tr[1].ix = 3; tr[1].iy = 0; tr[1].face = right; Timeout::set_up_timer(1, Timeout::procfall_down_oubliette, Timeout::reason_falling_down_oubliette); } break; case 7: { /* Gyro::special 7: stop falling down oubliette. */ tr[1].visible = false; Gyro::magics[10].op = Gyro::nix; stopwalking(); Timeout::lose_timer(Timeout::reason_falling_down_oubliette); Lucerna::mblit(12, 80, 38, 160, 3, 0); Lucerna::mblit(12, 80, 38, 160, 3, 1); Scrolls::display("Oh dear, you seem to be down the bottom of an oubliette."); Timeout::set_up_timer(200, Timeout::procmeet_avaroid, Timeout::reason_meeting_avaroid); } break; case 8: /* Gyro::special 8: leave du Lustie's room. */ if ((Gyro::dna.geida_follows) && (! Gyro::dna.lustie_is_asleep)) { Visa::dixi('q', 63); tr[2].turn(down); tr[2].stopwalk(); tr[2].call_eachstep = false; /* Geida */ Lucerna::gameover(); } break; case 9: { /* Gyro::special 9: lose Geida to Robin Hood... */ if (! Gyro::dna.geida_follows) return; /* DOESN'T COUNT: no Geida. */ tr[2].call_eachstep = false; /* She no longer follows Avvy around. */ tr[2].walkto(4); /* She walks to somewhere... */ tr[1].done(); /* Lose Avvy. */ Gyro::dna.user_moves_avvy = false; Timeout::set_up_timer(40, Timeout::procrobin_hood_and_geida, Timeout::reason_robin_hood_and_geida); } break; case 10: { /* Gyro::special 10: transfer north in catacombs. */ if ((Gyro::dna.cat_x == 4) && (Gyro::dna.cat_y == 1)) { /* Into Geida's room. */ if (Gyro::dna.obj[Gyro::key]) Visa::dixi('q', 62); else { Visa::dixi('q', 61); return; } } Lucerna::dusk(); Gyro::dna.cat_y -= 1; catamove(4); if (Gyro::dna.room != r__catacombs) return; Lucerna::delavvy(); switch ((Gyro::catamap[Gyro::dna.cat_y][Gyro::dna.cat_x] & 0xf00) >> 8) { case 0x1: apped(1, 12); break; case 0x3: apped(1, 11); break; default: apped(1, 4); } getback(); dawndelay(); } break; case 11: { /* Gyro::special 11: transfer east in catacombs. */ Lucerna::dusk(); Gyro::dna.cat_x += 1; catamove(1); if (Gyro::dna.room != r__catacombs) return; Lucerna::delavvy(); apped(1, 1); getback(); dawndelay(); } break; case 12: { /* Gyro::special 12: transfer south in catacombs. */ Lucerna::dusk(); Gyro::dna.cat_y += 1; catamove(2); if (Gyro::dna.room != r__catacombs) return; Lucerna::delavvy(); apped(1, 2); getback(); dawndelay(); } break; case 13: { /* Gyro::special 13: transfer west in catacombs. */ Lucerna::dusk(); Gyro::dna.cat_x -= 1; catamove(3); if (Gyro::dna.room != r__catacombs) return; Lucerna::delavvy(); apped(1, 3); getback(); dawndelay(); } break; } } void hide_in_the_cupboard(); void open_the_door(byte whither, byte ped, byte magicnum) /* This slides the door open. (The data really ought to be saved in the Also file, and will be next time. However, for now, they're here.) */ { switch (Gyro::dna.room) { case r__outsideyours: case r__outsidenottspub: case r__outsideducks: { Sequence::first_show(1); Sequence::then_show(2); Sequence::then_show(3); } break; case r__insidecardiffcastle: { Sequence::first_show(1); Sequence::then_show(5); } break; case r__avvysgarden: case r__entrancehall: case r__insideabbey: { Sequence::first_show(1); Sequence::then_show(2); } break; case r__musicroom: case r__outsideargentpub: { Sequence::first_show(5); Sequence::then_show(6); } break; case r__lusties: switch (magicnum) { case 14: if (Gyro::dna.avvys_in_the_cupboard) { hide_in_the_cupboard(); Sequence::first_show(8); Sequence::then_show(7); Sequence::start_to_close(); return; } else { apped(1, 6); tr[1].face = right; /* added by TT 12/3/1995 */ Sequence::first_show(8); Sequence::then_show(9); } break; case 12: { Sequence::first_show(4); Sequence::then_show(5); Sequence::then_show(6); } break; } break; } Sequence::then_flip(whither, ped); Sequence::start_to_open(); } void newspeed() { /* Given that you've just changed the speed in triptype.xs, this adjusts ix. */ warning("STUB: Trip::newspeed()"); } triptype *triptype::init(byte spritenum, bool do_check) { warning("STUB: Trip::init()"); return this; } void triptype::original() { quick = false; whichsprite = 177; } void triptype::andexor() { warning("STUB: Trip::andexor()"); } void triptype::turn(byte whichway) { if (whichway == 8) face = 0; else face = whichway; } void triptype::appear(int16 wx, int16 wy, byte wf) { x = (wx / 8) * 8; y = wy; ox[Gyro::cp] = wx; oy[Gyro::cp] = wy; turn(wf); visible = true; ix = 0; iy = 0; } bool triptype::collision_check() { byte fv; bool collision_check_result; for (fv = 1; fv <= numtr; fv ++) if (tr[fv].quick && (tr[fv].whichsprite != whichsprite) && ((x + a.xl) > tr[fv].x) && (x < (tr[fv].x + tr[fv].a.xl)) && (tr[fv].y == y)) { collision_check_result = true; return collision_check_result; } collision_check_result = false; return collision_check_result; } void triptype::walk() { warning("STUB: Trip::walk()"); } void triptype::bounce() { x = ox[Gyro::cp]; y = oy[Gyro::cp]; if (check_me) stopwalking(); else stopwalk(); Gyro::oncandopageswap = false; Lucerna::showrw(); Gyro::oncandopageswap = true; } int8 sgn(int16 x) { int8 sgn_result; if (x > 0) sgn_result = 1; else if (x < 0) sgn_result = -1; else sgn_result = 0; /* x=0 */ return sgn_result; } void triptype::walkto(byte pednum) { speed(sgn(Gyro::peds[pednum].x - x) * 4, sgn(Gyro::peds[pednum].y - y)); hx = Gyro::peds[pednum].x - a.xl / 2; hy = Gyro::peds[pednum].y - a.yl; homing = true; } void triptype::stophoming() { homing = false; } void triptype::homestep() { int16 temp; if ((hx == x) && (hy == y)) { /* touching the target */ stopwalk(); return; } ix = 0; iy = 0; if (hy != y) { temp = hy - y; if (temp > 4) iy = 4; else if (temp < -4) iy = -4; else iy = temp; } if (hx != x) { temp = hx - x; if (temp > 4) ix = 4; else if (temp < -4) ix = -4; else ix = temp; } } void triptype::speed(int8 xx, int8 yy) { ix = xx; iy = yy; if ((ix == 0) && (iy == 0)) return; /* no movement */ if (ix == 0) { /* No horz movement */ if (iy < 0) turn(up); else turn(down); } else { if (ix < 0) turn(left); else turn(right); } } void triptype::stopwalk() { ix = 0; iy = 0; homing = false; } void triptype::chatter() { Gyro::talkx = x + a.xl / 2; Gyro::talky = y; Gyro::talkf = a.fgc; Gyro::talkb = a.bgc; } void triptype::set_up_saver(trip_saver_type &v) { v.whichsprite = whichsprite; v.face = face; v.step = step; v.x = x; v.y = y; v.ix = ix; v.iy = iy; v.visible = visible; v.homing = homing; v.check_me = check_me; v.count = count; v.xw = xw; v.xs = xs; v.ys = ys; v.totalnum = totalnum; v.hx = hx; v.hy = hy; v.call_eachstep = call_eachstep; v.eachstep = eachstep; v.vanishifstill = vanishifstill; } void triptype::unload_saver(trip_saver_type v) { whichsprite = v.whichsprite; face = v.face; step = v.step; x = v.x; y = v.y; ix = v.ix; iy = v.iy; visible = v.visible; homing = v.homing; check_me = v.check_me; count = v.count; xw = v.xw; xs = v.xs; ys = v.ys; totalnum = v.totalnum; hx = v.hx; hy = v.hy; call_eachstep = v.call_eachstep; eachstep = v.eachstep; vanishifstill = v.vanishifstill; } void triptype::savedata(/*untyped_file &f*/) { warning("STUB: Timeout::savedata()"); } void triptype::loaddata(/*untyped_file &f*/) { warning("STUB: Timeout::loaddata()"); } triptype *triptype::done() { int16 gd, gm; Common::String xx; byte fv/*,nds*/; byte aa, bb; int32 id; uint16 soa; { adxtype &with = a; /* nds:=num div seq;*/ xw = with.xl / 8; if ((with.xl % 8) > 0) xw += 1; for (aa = 1; aa <= /*nds*seq*/ with.num; aa ++) { totalnum --; free(mani[totalnum]); free(sil[totalnum]); /* <<- Width of a siltype. */ } } quick = false; whichsprite = 177; return this; } getsettype *getsettype::init() { numleft = 0; /* initialise array pointer */ return this; } void getsettype::remember(Gyro::bytefield r) { numleft ++; warning("STUB: Timeout::getsettype::remember()"); gs[numleft] = r; } void getsettype::recall(Gyro::bytefield &r) { r = gs[numleft]; numleft --; } void rwsp(byte t, byte r) { { switch (r) { case up: tr[t].speed(0, -tr[t].ys); break; case down: tr[t].speed(0, tr[t].ys); break; case left: tr[t].speed(-tr[t].xs, 0); break; case right: tr[t].speed(tr[t].xs, 0); break; case ul: tr[t].speed(-tr[t].xs, -tr[t].ys); break; case ur: tr[t].speed(tr[t].xs, -tr[t].ys); break; case dl: tr[t].speed(-tr[t].xs, tr[t].ys); break; case dr: tr[t].speed(tr[t].xs, tr[t].ys); break; } } } void apped(byte trn, byte np) { tr[trn].appear(tr[trn].x - tr[trn].a.xl / 2, tr[trn].y - tr[trn].a.yl, Gyro::peds[np].dir); rwsp(trn, Gyro::peds[np].dir); } void getback(); static Gyro::bytefield r; /* function overlap(x1,y1,x2,y2,x3,y3,x4,y4:uint16):bool; begin { By De Morgan's law: } overlap:=(x2>=x3) and (x4>=x1) and (y2>=y3) and (y4>=y1); end;*/ /* x1,x2 - as Gyro::bytefield, but *8. y1,y2 - as Gyro::bytefield. x3,y3 = mx,my. x4,y4 = mx+16,my+16. */ static bool overlaps_with_mouse() { bool overlaps_with_mouse_result; overlaps_with_mouse_result = (r.x2 * 8 >= Gyro::mx) && (Gyro::mx + 16 >= r.x1 * 8) && (r.y2 >= Gyro::my) && (Gyro::my + 16 >= r.y1); return overlaps_with_mouse_result; } void getback() { byte fv; bool endangered; endangered = false; /* Super_Off;*/ { while (getset[1 - Gyro::cp].numleft > 0) { getset[1 - Gyro::cp].recall(r); /* if overlaps_with_mouse and not endangered then begin endangered:=true; blitfix; Super_Off; end;*/ Lucerna::mblit(r.x1, r.y1, r.x2, r.y2, 3, 1 - Gyro::cp); } } Lucerna::blitfix(); /*if endangered then*/ /*Super_On;*/ } /* Eachstep procedures: */ void follow_avvy_y(byte tripnum) { if (tr[1].face == left) return; if (tr[tripnum].homing) tr[tripnum].hy = tr[1].y; else { if (tr[tripnum].y < tr[1].y) tr[tripnum].y += 1; else if (tr[tripnum].y > tr[1].y) tr[tripnum].y -= 1; else return; if (tr[tripnum].ix == 0) { tr[tripnum].step += 1; if (tr[tripnum].step == tr[tripnum].a.seq) tr[tripnum].step = 0; tr[tripnum].count = 0; } } } void back_and_forth(byte tripnum) { if (! tr[tripnum].homing) { if (tr[tripnum].face == right) tr[tripnum].walkto(4); else tr[tripnum].walkto(5); } } void face_avvy(byte tripnum) { if (! tr[tripnum].homing) { if (tr[1].x >= tr[tripnum].x) tr[tripnum].face = right; else tr[tripnum].face = left; } } void arrow_procs(byte tripnum) { byte fv; if (tr[tripnum].homing) { /* Arrow is still in flight. */ /* We must check whether or not the arrow has collided tr[tripnum] Avvy's head. This is so if: a) the bottom of the arrow is below Avvy's head, b) the left of the arrow is left of the right of Avvy's head, and c) the right of the arrow is right of the left of Avvy's head. */ if (((tr[tripnum].y + tr[tripnum].a.yl) >= tr[1].y) /* A */ && (tr[tripnum].x <= (tr[1].x + tr[1].a.xl)) /* B */ && ((tr[tripnum].x + tr[tripnum].a.xl) >= tr[1].x)) { /* C */ /* OK, it's hit him... what now? */ tr[2].call_eachstep = false; /* prevent recursion. */ Visa::dixi('Q', 47); /* Complaint! */ tr[tripnum].done(); /* Deallocate the arrow. */ /* tr[1].done; { Deallocate normal pic of Avvy. } off; for fv:=0 to 1 do begin cp:=1-cp; getback; end; on;*/ Lucerna::gameover(); Gyro::dna.user_moves_avvy = false; /* Stop the user from moving him. */ Timeout::set_up_timer(55, Timeout::procnaughty_duke, Timeout::reason_naughty_duke); } } else { /* Arrow has hit the wall! */ tr[tripnum].done(); /* Deallocate the arrow. */ Celer::show_one(3); /* Show pic of arrow stuck into the door. */ Gyro::dna.arrow_in_the_door = true; /* So that we can pick it up. */ } } /*procedure Spludwick_procs(tripnum:byte); var fv:byte; begin with tr[tripnum] do if not homing then { We only need to do anything if Spludwick *stops* walking. } with Gyro::dna do begin inc(DogfoodPos); if DogfoodPos=8 then DogfoodPos:=1; walkto(DogfoodPos); end; end;*/ void grab_avvy(byte tripnum) { /* For Friar Tuck, in Nottingham. */ byte fv; int16 tox, toy; tox = tr[1].x + 17; toy = tr[1].y - 1; if ((tr[tripnum].x == tox) && (tr[tripnum].y == toy)) { tr[tripnum].call_eachstep = false; tr[tripnum].face = left; tr[tripnum].stopwalk(); /* ... whatever ... */ } else { /* Still some way to go. */ if (tr[tripnum].x < tox) { tr[tripnum].x += 5; if (tr[tripnum].x > tox) tr[tripnum].x = tox; } if (tr[tripnum].y < toy) tr[tripnum].y += 1; tr[tripnum].step += 1; if (tr[tripnum].step == tr[tripnum].a.seq) tr[tripnum].step = 0; } } void geida_procs(byte tripnum); static void take_a_step(byte &tripnum) { if (tr[tripnum].ix == 0) { tr[tripnum].step += 1; if (tr[tripnum].step == tr[tripnum].a.seq) tr[tripnum].step = 0; tr[tripnum].count = 0; } } static void spin(byte whichway, byte &tripnum) { if (tr[tripnum].face != whichway) { tr[tripnum].face = whichway; if (tr[tripnum].whichsprite == 2) return; /* Not for Spludwick */ Gyro::dna.geida_spin += 1; Gyro::dna.geida_time = 20; if (Gyro::dna.geida_spin == 5) { Scrolls::display("Steady on, Avvy, you'll make the poor girl dizzy!"); Gyro::dna.geida_spin = 0; Gyro::dna.geida_time = 0; /* knock out records */ } } } void geida_procs(byte tripnum) { if (Gyro::dna.geida_time > 0) { Gyro::dna.geida_time -= 1; if (Gyro::dna.geida_time == 0) Gyro::dna.geida_spin = 0; } if (tr[tripnum].y < (tr[1].y - 2)) { /* Geida is further from the screen than Avvy. */ spin(down, tripnum); tr[tripnum].iy = 1; tr[tripnum].ix = 0; take_a_step(tripnum); return; } else if (tr[tripnum].y > (tr[1].y + 2)) { /* Avvy is further from the screen than Geida. */ spin(up, tripnum); tr[tripnum].iy = -1; tr[tripnum].ix = 0; take_a_step(tripnum); return; } tr[tripnum].iy = 0; if (tr[tripnum].x < tr[1].x - tr[1].xs * 8) { tr[tripnum].ix = tr[1].xs; spin(right, tripnum); take_a_step(tripnum); } else if (tr[tripnum].x > tr[1].x + tr[1].xs * 8) { tr[tripnum].ix = -tr[1].xs; spin(left, tripnum); take_a_step(tripnum); } else tr[tripnum].ix = 0; } /* That's all... */ void call_andexors() { byte order[5]; byte fv, temp; bool ok; for (int i = 0; i < 5; i++) order[i] = 0; for (fv = 1; fv <= numtr; fv ++) { if (tr[fv].quick && tr[fv].visible) order[fv] = fv; } do { ok = true; for (fv = 1; fv <= 4; fv ++) if (((order[fv] != 0) && (order[fv + 1] != 0)) && (tr[order[fv]].y > tr[order[fv + 1]].y)) { /* Swap them! */ temp = order[fv]; order[fv] = order[fv + 1]; order[fv + 1] = temp; ok = false; } } while (!ok); for (fv = 1; fv <= 5; fv ++) if (order[fv] > 0) tr[order[fv]].andexor(); } void trippancy_link() { byte fv; if (Gyro::ddmnow | Gyro::ontoolbar | Gyro::seescroll) return; for (fv = 1; fv <= numtr; fv ++) { if (tr[fv].quick) tr[fv].walk(); } call_andexors(); for (fv = 1; fv <= numtr; fv ++) { triptype &with = tr[fv]; if (with.quick && with.call_eachstep) { switch (tr[fv].eachstep) { case procfollow_avvy_y : follow_avvy_y(fv); break; case procback_and_forth : back_and_forth(fv); break; case procface_avvy : face_avvy(fv); break; case procarrow_procs : arrow_procs(fv); break; /* PROCSpludwick_procs : spludwick_procs(fv);*/ case procgrab_avvy : grab_avvy(fv); break; case procgeida_procs : geida_procs(fv); break; } } } if (mustexclaim) { mustexclaim = false; Visa::dixi('x', saywhat); } } void get_back_loretta() { byte fv; /* for fv:=1 to numtr do with tr[fv] do if quick then getback;*/ for (fv = 1; fv <= numtr; fv ++) if (tr[fv].quick) { getback(); return; } /* for fv:=0 to 1 do begin cp:=1-cp; getback; end;*/ } void stopwalking() { tr[1].stopwalk(); Gyro::dna.rw = stopped; if (Gyro::alive) tr[1].step = 1; } void tripkey(char dir) { if ((Gyro::ctrl == Gyro::cjoy) | (! Gyro::dna.user_moves_avvy)) return; { triptype &with = tr[1]; { switch (dir) { case 'H': if (Gyro::dna.rw != up) { Gyro::dna.rw = up; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'P': if (Gyro::dna.rw != down) { Gyro::dna.rw = down; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'K': if (Gyro::dna.rw != left) { Gyro::dna.rw = left; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'M': if (Gyro::dna.rw != right) { Gyro::dna.rw = right; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'I': if (Gyro::dna.rw != ur) { Gyro::dna.rw = ur; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'Q': if (Gyro::dna.rw != dr) { Gyro::dna.rw = dr; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'O': if (Gyro::dna.rw != dl) { Gyro::dna.rw = dl; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'G': if (Gyro::dna.rw != ul) { Gyro::dna.rw = ul; rwsp(1, Gyro::dna.rw); } else stopwalking(); break; case 'L': stopwalking(); break; } } } } void readstick() { warning("STUB: Trip::readstick()"); } void getsetclear() { byte fv; for (fv = 0; fv <= 1; fv ++) getset[fv].init(); } void hide_in_the_cupboard() { const char nowt = 250; /* As in Acci. */ if (Gyro::dna.avvys_in_the_cupboard) { if (Gyro::dna.wearing == nowt) Scrolls::display("\6AVVY!\22 Get dressed first!"); else { tr[1].visible = true; Gyro::dna.user_moves_avvy = true; apped(1, 3); /* Walk out of the cupboard. */ Scrolls::display("You leave the cupboard. Nice to be out of there!"); Gyro::dna.avvys_in_the_cupboard = false; Sequence::first_show(8); Sequence::then_show(7); Sequence::start_to_close; } } else { /* Not hiding in the cupboard */ tr[1].visible = false; Gyro::dna.user_moves_avvy = false; Scrolls::display(Common::String("You walk into the room...\20It seems to be an empty, ") + "but dusty, cupboard. Hmmmm... you leave the door slightly open to " + "avoid suffocation."); Gyro::dna.avvys_in_the_cupboard = true; Celer::show_one(8); } } void fliproom(byte room, byte ped); static int16 beforex, beforey; static void tidy_after_mouse(); static void tidy_up(int16 a, int16 b, int16 c, int16 d) { warning("STUB: Trip::tidy_up()"); } static void tidy_after_mouse() { tidy_up(beforex, beforey, beforex + 15, beforey + 15); Gyro::xycheck(); tidy_up(Gyro::mx, Gyro::my, Gyro::mx + 15, Gyro::my + 15); } void fliproom(byte room, byte ped) { byte fv; if (! Gyro::alive) { /* You can't leave the room if you're dead. */ tr[1].ix = 0; tr[1].iy = 0; /* Stop him from moving. */ return; } if ((ped == 177) && (Gyro::dna.room == r__lusties)) { hide_in_the_cupboard(); return; } if ((Gyro::dna.jumpstatus > 0) && (Gyro::dna.room == r__insidecardiffcastle)) { /* You can't *jump* out of Cardiff Castle! */ tr[1].ix = 0; return; } Gyro::xycheck(); beforex = Gyro::mx; beforey = Gyro::my; Lucerna::exitroom(Gyro::dna.room); Lucerna::dusk(); getsetclear(); for (fv = 2; fv <= numtr; fv ++) { if (tr[fv].quick) tr[fv].done(); } /* Deallocate sprite */ if (Gyro::dna.room == r__lustiesroom) Gyro::dna.enter_catacombs_from_lusties_room = true; Lucerna::enterroom(room, ped); apped(1, ped); Gyro::dna.enter_catacombs_from_lusties_room = false; Gyro::oldrw = Gyro::dna.rw; Gyro::dna.rw = tr[1].face; Lucerna::showrw; for (fv = 0; fv <= 1; fv ++) { Gyro::cp = 1 - Gyro::cp; getback(); } Lucerna::dawn; /* Tidy up after mouse. I know it's a kludge... */ /* tidy_after_mouse;*/ } bool infield(byte which) { /* returns True if you're within field "which" */ int16 yy; yy = tr[1].y + tr[1].a.yl; return (tr[1].x >= Gyro::fields[which].x1) && (tr[1].x <= Gyro::fields[which].x2) && (yy >= Gyro::fields[which].y1) && (yy <= Gyro::fields[which].y2); } bool neardoor() { /* returns True if you're near a door! */ int16 ux, uy; byte fv; bool nd; bool neardoor_result; if (Gyro::numfields < 9) { /* there ARE no doors here! */ neardoor_result = false; return neardoor_result; } ux = tr[1].x; uy = tr[1].y + tr[1].a.yl; nd = false; for (fv = 9; fv <= Gyro::numfields; fv ++) { Gyro::fields[fv]; if ((ux >= Gyro::fields[fv].x1) && (ux <= Gyro::fields[fv].x2) && (uy >= Gyro::fields[fv].y1) && (uy <= Gyro::fields[fv].y2)) nd = true; } return nd; } void new_game_for_trippancy() { /* Called by gyro.newgame */ tr[1].visible = false; } void triptype::save_data_to_mem(uint16 &where) { warning("STUB: Trip::save_data_to_mem()"); } void triptype::load_data_from_mem(uint16 &where) { warning("STUB: Trip::load_data_from_mem()"); } } // End of namespace Trip. } // End of namespace Avalanche.