diff options
Diffstat (limited to 'engines/lastexpress/fight')
-rw-r--r-- | engines/lastexpress/fight/fight.cpp | 409 | ||||
-rw-r--r-- | engines/lastexpress/fight/fight.h | 125 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter.cpp | 249 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter.h | 123 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_anna.cpp | 187 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_anna.h | 48 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_ivo.cpp | 245 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_ivo.h | 51 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_milos.cpp | 222 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_milos.h | 51 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_salko.cpp | 202 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_salko.h | 51 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_vesna.cpp | 265 | ||||
-rw-r--r-- | engines/lastexpress/fight/fighter_vesna.h | 51 |
14 files changed, 2279 insertions, 0 deletions
diff --git a/engines/lastexpress/fight/fight.cpp b/engines/lastexpress/fight/fight.cpp new file mode 100644 index 0000000000..b832d46a60 --- /dev/null +++ b/engines/lastexpress/fight/fight.cpp @@ -0,0 +1,409 @@ +/* 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. + * + */ + +#include "lastexpress/fight/fight.h" + +#include "lastexpress/fight/fighter_anna.h" +#include "lastexpress/fight/fighter_ivo.h" +#include "lastexpress/fight/fighter_milos.h" +#include "lastexpress/fight/fighter_salko.h" +#include "lastexpress/fight/fighter_vesna.h" + +#include "lastexpress/data/cursor.h" +#include "lastexpress/data/sequence.h" + +#include "lastexpress/game/inventory.h" +#include "lastexpress/game/logic.h" +#include "lastexpress/game/object.h" +#include "lastexpress/game/scenes.h" +#include "lastexpress/game/state.h" + +#include "lastexpress/sound/queue.h" + +#include "lastexpress/graphics.h" +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" +#include "lastexpress/resource.h" + +namespace LastExpress { + +Fight::FightData::FightData() { + player = NULL; + opponent = NULL; + + index = 0; + + isFightRunning = false; +} + +Fight::FightData::~FightData() { + SAFE_DELETE(player); + SAFE_DELETE(opponent); +} + +Fight::Fight(LastExpressEngine *engine) : _engine(engine), _data(NULL), _endType(kFightEndLost), _state(0), _handleTimer(false) { +} + +Fight::~Fight() { + clearData(); + _data = NULL; + + // Zero passed pointers + _engine = NULL; +} + +////////////////////////////////////////////////////////////////////////// +// Events +////////////////////////////////////////////////////////////////////////// +void Fight::eventMouse(const Common::Event &ev) { + if (!_data || _data->index) + return; + + // TODO move all the egg handling to inventory functions + + getFlags()->mouseLeftClick = false; + getFlags()->shouldRedraw = false; + getFlags()->mouseRightClick = false; + + if (ev.mouse.x < 608 || ev.mouse.y < 448 || ev.mouse.x >= 640 || ev.mouse.x >= 480) { + + // Handle right button click + if (ev.type == Common::EVENT_RBUTTONUP) { + getSoundQueue()->removeFromQueue(kEntityTables0); + setStopped(); + + getGlobalTimer() ? _state = 0 : ++_state; + + getFlags()->mouseRightClick = true; + } + + if (_handleTimer) { + // Timer expired => show with full brightness + if (!getGlobalTimer()) + getInventory()->drawBlinkingEgg(); + + _handleTimer = false; + } + + // Check hotspots + Scene *scene = getScenes()->get(getState()->scene); + SceneHotspot *hotspot = NULL; + + if (!scene->checkHotSpot(ev.mouse, &hotspot)) { + _engine->getCursor()->setStyle(kCursorNormal); + } else { + _engine->getCursor()->setStyle((CursorStyle)hotspot->cursor); + + // Call player function + if (_data->player->canInteract((Fighter::FightAction)hotspot->action)) { + if (ev.type == Common::EVENT_LBUTTONUP) + _data->player->handleAction((Fighter::FightAction)hotspot->action); + } else { + _engine->getCursor()->setStyle(kCursorNormal); + } + } + } else { + // Handle clicks on menu icon + + if (!_handleTimer) { + // Timer expired => show with full brightness + if (!getGlobalTimer()) + getInventory()->drawBlinkingEgg(); + + _handleTimer = true; + } + + // Stop fight if clicked + if (ev.type == Common::EVENT_LBUTTONUP) { + _handleTimer = false; + getSoundQueue()->removeFromQueue(kEntityTables0); + bailout(kFightEndExit); + } + + // Reset timer on right click + if (ev.type == Common::EVENT_RBUTTONUP) { + if (getGlobalTimer()) { + if (getSoundQueue()->isBuffered("TIMER")) + getSoundQueue()->removeFromQueue("TIMER"); + + setGlobalTimer(900); + } + } + } + + getFlags()->shouldRedraw = true; +} + +void Fight::eventTick(const Common::Event &ev) { + handleTick(ev, true); +} + +void Fight::handleTick(const Common::Event &ev, bool isProcessing) { + // TODO move all the egg handling to inventory functions + + // Blink egg + if (getGlobalTimer()) { + warning("[Fight::handleTick] Egg blinking not implemented"); + } + + if (!_data || _data->index) + return; + + SceneHotspot *hotspot = NULL; + if (!getScenes()->get(getState()->scene)->checkHotSpot(ev.mouse, &hotspot) || !_data->player->canInteract((Fighter::FightAction)hotspot->action)) { + _engine->getCursor()->setStyle(kCursorNormal); + } else { + _engine->getCursor()->setStyle((CursorStyle)hotspot->cursor); + } + + _data->player->update(); + _data->opponent->update(); + + // Draw sequences + if (!_data->isFightRunning) + return; + + if (isProcessing) + getScenes()->drawFrames(true); + + if (_data->index) { + // Set next sequence name index + _data->index--; + _data->sequences[_data->index] = loadSequence(_data->names[_data->index]); + } +} + +////////////////////////////////////////////////////////////////////////// +// Setup +////////////////////////////////////////////////////////////////////////// +Fight::FightEndType Fight::setup(FightType type) { + if (_data) + error("[Fight::setup] Calling fight setup again while a fight is already in progress"); + + ////////////////////////////////////////////////////////////////////////// + // Prepare UI & state + if (_state >= 5 && (type == kFightSalko || type == kFightVesna)) { + _state = 0; + return kFightEndWin; + } + + getInventory()->showHourGlass(); + // TODO events function + getFlags()->flag_0 = false; + getFlags()->mouseRightClick = false; + getEntities()->reset(); + + // Compute scene to use + SceneIndex sceneIndex; + switch(type) { + default: + sceneIndex = kSceneFightDefault; + break; + + case kFightMilos: + sceneIndex = (getObjects()->get(kObjectCompartment1).location2 < kObjectLocation3) ? kSceneFightMilos : kSceneFightMilosBedOpened; + break; + + case kFightAnna: + sceneIndex = kSceneFightAnna; + break; + + case kFightIvo: + sceneIndex = kSceneFightIvo; + break; + + case kFightSalko: + sceneIndex = kSceneFightSalko; + break; + + case kFightVesna: + sceneIndex = kSceneFightVesna; + break; + } + + if (getFlags()->shouldRedraw) { + getFlags()->shouldRedraw = false; + askForRedraw(); + //redrawScreen(); + } + + // Load the scene object + Scene *scene = getScenes()->get(sceneIndex); + + // Update game entities and state + getEntityData(kEntityPlayer)->entityPosition = scene->entityPosition; + getEntityData(kEntityPlayer)->location = scene->location; + + getState()->scene = sceneIndex; + + getFlags()->flag_3 = true; + + // Draw the scene + _engine->getGraphicsManager()->draw(scene, GraphicsManager::kBackgroundC); + // FIXME move to start of fight? + askForRedraw(); + redrawScreen(); + + ////////////////////////////////////////////////////////////////////////// + // Setup the fight + _data = new FightData; + loadData(type); + + // Show opponents & egg button + Common::Event emptyEvent; + handleTick(emptyEvent, false); + getInventory()->drawEgg(); + + // Start fight + _endType = kFightEndLost; + while (_data->isFightRunning) { + if (_engine->handleEvents()) + continue; + + getSoundQueue()->updateQueue(); + } + + // Cleanup after fight is over + clearData(); + + return _endType; +} + +////////////////////////////////////////////////////////////////////////// +// Status +////////////////////////////////////////////////////////////////////////// +void Fight::setStopped() { + if (_data) + _data->isFightRunning = false; +} + +void Fight::bailout(FightEndType type) { + _state = 0; + _endType = type; + setStopped(); +} + +////////////////////////////////////////////////////////////////////////// +// Cleanup +////////////////////////////////////////////////////////////////////////// +void Fight::clearData() { + if (!_data) + return; + + // Clear data + SAFE_DELETE(_data); + + _engine->restoreEventHandlers(); +} + +////////////////////////////////////////////////////////////////////////// +// Loading +////////////////////////////////////////////////////////////////////////// +void Fight::loadData(FightType type) { + if (!_data) + error("[Fight::loadData] Data not initialized"); + + switch (type) { + default: + break; + + case kFightMilos: + _data->player = new FighterPlayerMilos(_engine); + _data->opponent = new FighterOpponentMilos(_engine); + break; + + case kFightAnna: + _data->player = new FighterPlayerAnna(_engine); + _data->opponent = new FighterOpponentAnna(_engine); + break; + + case kFightIvo: + _data->player = new FighterPlayerIvo(_engine); + _data->opponent = new FighterOpponentIvo(_engine); + break; + + case kFightSalko: + _data->player = new FighterPlayerSalko(_engine); + _data->opponent = new FighterOpponentSalko(_engine); + break; + + case kFightVesna: + _data->player = new FighterPlayerVesna(_engine); + _data->opponent = new FighterOpponentVesna(_engine); + break; + } + + if (!_data->player || !_data->opponent) + error("[Fight::loadData] Error loading fight data (type=%d)", type); + + // Setup opponent pointers + setOpponents(); + + ////////////////////////////////////////////////////////////////////////// + // Start running the fight + _data->isFightRunning = true; + + if (_state < 5) { + _data->player->setSequenceAndDraw(0, Fighter::kFightSequenceType0); + _data->opponent->setSequenceAndDraw(0, Fighter::kFightSequenceType0); + goto end_load; + } + + switch(type) { + default: + break; + + case kFightMilos: + _data->opponent->setCountdown(1); + _data->player->setSequenceAndDraw(4, Fighter::kFightSequenceType0); + _data->opponent->setSequenceAndDraw(0, Fighter::kFightSequenceType0); + break; + + case kFightIvo: + _data->opponent->setCountdown(1); + _data->player->setSequenceAndDraw(3, Fighter::kFightSequenceType0); + _data->opponent->setSequenceAndDraw(6, Fighter::kFightSequenceType0); + break; + + case kFightVesna: + _data->opponent->setCountdown(1); + _data->player->setSequenceAndDraw(0, Fighter::kFightSequenceType0); + _data->player->setSequenceAndDraw(3, Fighter::kFightSequenceType2); + _data->opponent->setSequenceAndDraw(5, Fighter::kFightSequenceType0); + break; + } + +end_load: + // Setup event handlers + _engine->backupEventHandlers(); + SET_EVENT_HANDLERS(Fight, this); +} + +void Fight::setOpponents() { + _data->player->setOpponent(_data->opponent); + _data->opponent->setOpponent(_data->player); + + _data->player->setFight(this); + _data->opponent->setFight(this); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/fight/fight.h b/engines/lastexpress/fight/fight.h new file mode 100644 index 0000000000..fffb520789 --- /dev/null +++ b/engines/lastexpress/fight/fight.h @@ -0,0 +1,125 @@ +/* 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. + * + */ + +#ifndef LASTEXPRESS_FIGHT_H +#define LASTEXPRESS_FIGHT_H + +/* + Fight structure + --------------- + uint32 {4} - player struct + uint32 {4} - opponent struct + uint32 {4} - hasLost flag + + byte {1} - isRunning + + Fight participant structure + --------------------------- + uint32 {4} - function pointer + uint32 {4} - pointer to fight structure + uint32 {4} - pointer to opponent (fight participant structure) + uint32 {4} - array of sequences + uint32 {4} - number of sequences + uint32 {4} - ?? + uint32 {4} - ?? + uint32 {4} - ?? + uint32 {4} - ?? + uint32 {4} - ?? + uint32 {4} - ?? + uint32 {4} - ?? + uint32 {4} - ?? + uint16 {2} - ?? + uint16 {2} - ?? - only for opponent structure + uint32 {4} - ?? - only for opponent structure + +*/ + +#include "lastexpress/shared.h" + +#include "lastexpress/eventhandler.h" + +namespace LastExpress { + +class LastExpressEngine; +class Sequence; + +class Fighter; +class Opponent; + +class Fight : public EventHandler { +public: + enum FightEndType { + kFightEndWin = 0, + kFightEndLost = 1, + kFightEndExit = 2 + }; + + Fight(LastExpressEngine *engine); + ~Fight(); + + FightEndType setup(FightType type); + + void eventMouse(const Common::Event &ev); + void eventTick(const Common::Event &ev); + + // State + bool isRunning() { return _data->isFightRunning; } + void setRunningState(bool state) { _data->isFightRunning = state; } + void bailout(FightEndType type); + void setStopped(); + void resetState() { _state = 0; } + void setEndType(FightEndType endType) { _endType = endType; } + +private: + struct FightData { + Fighter *player; + Opponent *opponent; + int32 index; + + Sequence *sequences[20]; + Common::String names[20]; + + bool isFightRunning; + + FightData(); + ~FightData(); + }; + + LastExpressEngine *_engine; + FightData *_data; + FightEndType _endType; + int _state; + + bool _handleTimer; + + // Events + void handleTick(const Common::Event &ev, bool unknown); + + // Data + void loadData(FightType type); + void clearData(); + void setOpponents(); +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_FIGHT_H diff --git a/engines/lastexpress/fight/fighter.cpp b/engines/lastexpress/fight/fighter.cpp new file mode 100644 index 0000000000..bae7728a2b --- /dev/null +++ b/engines/lastexpress/fight/fighter.cpp @@ -0,0 +1,249 @@ +/* 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. + * + */ + +#include "lastexpress/fight/fighter.h" + +#include "lastexpress/data/sequence.h" + +#include "lastexpress/game/scenes.h" + +#include "lastexpress/sound/sound.h" + +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" + +namespace LastExpress { + +Fighter::Fighter(LastExpressEngine *engine) : _engine(engine) { + _opponent = NULL; + _fight = NULL; + + _sequenceIndex = 0; + _sequence = NULL; + _frame = NULL; + _frameIndex = 0; + + _field_24 = 0; + + _action = kFightAction101; + _sequenceIndex2 = 0; + + _countdown = 1; + + _field_34 = 0; +} + +Fighter::~Fighter() { + clearSequences(); +} + +////////////////////////////////////////////////////////////////////////// +// Cleanup +////////////////////////////////////////////////////////////////////////// +void Fighter::clearSequences() { + // The original game resets the function pointers to default values, just before deleting the struct + + getScenes()->removeAndRedraw(&_frame, false); + + // Free sequences + for (int i = 0; i < (int)_sequences.size(); i++) + SAFE_DELETE(_sequences[i]); +} + +////////////////////////////////////////////////////////////////////////// +// Drawing +////////////////////////////////////////////////////////////////////////// +void Fighter::setSequenceAndDraw(uint32 sequenceIndex, FightSequenceType type) { + if (_sequences.size() < sequenceIndex) + return; + + switch (type) { + default: + break; + + case kFightSequenceType0: + if (_sequenceIndex) + return; + + _sequence = _sequences[sequenceIndex]; + _sequenceIndex = sequenceIndex; + draw(); + break; + + case kFightSequenceType1: + _sequence = _sequences[sequenceIndex]; + _sequenceIndex = sequenceIndex; + _sequenceIndex2 = 0; + draw(); + break; + + case kFightSequenceType2: + _sequenceIndex2 = sequenceIndex; + break; + } +} + +void Fighter::draw() { + getScenes()->removeAndRedraw(&_frame, false); + + _frameIndex = 0; + _field_24 = 0; +} + +////////////////////////////////////////////////////////////////////////// +// Processing +////////////////////////////////////////////////////////////////////////// +void Fighter::process() { + if (!_sequence) { + if (_frame) { + getScenes()->removeFromQueue(_frame); + getScenes()->setCoordinates(_frame); + } + SAFE_DELETE(_frame); + return; + } + + if (_sequence->count() <= _frameIndex) { + switch(_action) { + default: + break; + + case kFightAction101: + setSequenceAndDraw(_sequenceIndex2, kFightSequenceType1); + _sequenceIndex2 = 0; + break; + + case kFightActionResetFrame: + _frameIndex = 0; + break; + + case kFightAction103: + setSequenceAndDraw(0, kFightSequenceType1); + handleAction(kFightAction101); + _opponent->setSequenceAndDraw(0, kFightSequenceType1); + _opponent->handleAction(kFightAction101); + _opponent->update(); + break; + + case kFightActionWin: + _fight->bailout(Fight::kFightEndWin); + break; + + case kFightActionLost: + _fight->bailout(Fight::kFightEndLost); + break; + } + } + + if (_fight->isRunning()) { + + // Get the current sequence frame + SequenceFrame *frame = new SequenceFrame(_sequence, (uint16)_frameIndex); + frame->getInfo()->location = 1; + + if (_frame == frame) { + delete frame; + return; + } + + getSound()->playFightSound(frame->getInfo()->soundAction, frame->getInfo()->field_31); + + // Add current frame to queue and advance + getScenes()->addToQueue(frame); + _frameIndex++; + + if (_frame) { + getScenes()->removeFromQueue(_frame); + + if (!frame->getInfo()->field_2E) + getScenes()->setCoordinates(_frame); + } + + // Replace by new frame + delete _frame; + _frame = frame; + } +} + +////////////////////////////////////////////////////////////////////////// +// Default actions +////////////////////////////////////////////////////////////////////////// +void Fighter::handleAction(FightAction action) { + switch (action) { + default: + return; + + case kFightAction101: + break; + + case kFightActionResetFrame: + _countdown--; + break; + + case kFightAction103: + _opponent->handleAction(kFightActionResetFrame); + break; + + case kFightActionWin: + _fight->setEndType(Fight::kFightEndWin); + _opponent->handleAction(kFightActionResetFrame); + break; + + case kFightActionLost: + _fight->setEndType(Fight::kFightEndLost); + _opponent->handleAction(kFightActionResetFrame); + break; + } + + // Update action + _action = action; +} + +bool Fighter::canInteract(FightAction /*action = kFightActionNone*/ ) { + return (_action == kFightAction101 && !_sequenceIndex); +} + +void Fighter::update() { + process(); + + if (_frame) + _frame->getInfo()->location = (_action == kFightActionResetFrame ? 2 : 0); +} + +void Opponent::update() { + process(); + + if (_field_38 && !_sequenceIndex) + _field_38--; + + if (_frame) + _frame->getInfo()->location = 1; +} + +////////////////////////////////////////////////////////////////////////// +// Helpers +////////////////////////////////////////////////////////////////////////// +bool Fighter::checkFrame(uint32 val) { + return (_frame->getInfo()->field_33 & val); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/fight/fighter.h b/engines/lastexpress/fight/fighter.h new file mode 100644 index 0000000000..e37fe49d86 --- /dev/null +++ b/engines/lastexpress/fight/fighter.h @@ -0,0 +1,123 @@ +/* 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. + * + */ + +#ifndef LASTEXPRESS_FIGHTER_H +#define LASTEXPRESS_FIGHTER_H + +#include "lastexpress/fight/fight.h" + +#include "common/array.h" + +namespace LastExpress { + +class Fight; +class Sequence; +class SequenceFrame; + +class Fighter { +public: + enum FightAction { + kFightActionNone = 0, + kFightAction1 = 1, + kFightAction2 = 2, + kFightAction3 = 3, + kFightAction4 = 4, + kFightAction5 = 5, + kFightAction101 = 101, + kFightActionResetFrame = 102, + kFightAction103 = 103, + kFightActionWin = 104, + kFightActionLost = 105, + kFightAction128 = 128, + kFightAction129 = 129, + kFightAction130 = 130, + kFightAction131 = 131, + kFightAction132 = 132 + }; + + enum FightSequenceType { + kFightSequenceType0 = 0, + kFightSequenceType1 = 1, + kFightSequenceType2 = 2 + }; + + Fighter(LastExpressEngine *engine); + virtual ~Fighter(); + + // Default functions + virtual void handleAction(FightAction action); + virtual void update(); + virtual bool canInteract(FightAction action = kFightActionNone); + + // Drawing + void setSequenceAndDraw(uint32 sequenceIndex, FightSequenceType type); + + // Accessors + void setOpponent(Fighter *opponent) { _opponent = opponent; } + void setCountdown(int32 countdown) { _countdown = countdown; } + void setFight(Fight *fight) { _fight = fight; } + + int getCountdown() { return _countdown; } + uint32 getSequenceIndex() { return _sequenceIndex; } + uint32 getField34() { return _field_34; } + +protected: + LastExpressEngine *_engine; + Fight *_fight; + Fighter *_opponent; + Sequence *_sequence; + SequenceFrame *_frame; + uint32 _sequenceIndex; + Common::Array<Sequence *> _sequences; + uint32 _frameIndex; + uint32 _field_24; + FightAction _action; + uint32 _sequenceIndex2; + int32 _countdown; // countdown before loosing ? + uint32 _field_34; + + // Drawing and processing + void draw(); + void process(); + + // Cleanup + void clearSequences(); + + // Helpers + bool checkFrame(uint32 val); +}; + +class Opponent : public Fighter { +public: + Opponent(LastExpressEngine *engine) : Fighter(engine) { + _field_38 = 0; + } + + virtual void update(); + +protected: + int32 _field_38; +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_FIGHTER_H diff --git a/engines/lastexpress/fight/fighter_anna.cpp b/engines/lastexpress/fight/fighter_anna.cpp new file mode 100644 index 0000000000..c7660cab1a --- /dev/null +++ b/engines/lastexpress/fight/fighter_anna.cpp @@ -0,0 +1,187 @@ +/* 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. + * + */ + +#include "lastexpress/fight/fighter_anna.h" + +#include "lastexpress/data/sequence.h" + +#include "lastexpress/sound/queue.h" +#include "lastexpress/sound/sound.h" + +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" +#include "lastexpress/resource.h" + +namespace LastExpress { + +////////////////////////////////////////////////////////////////////////// +// Player +////////////////////////////////////////////////////////////////////////// +FighterPlayerAnna::FighterPlayerAnna(LastExpressEngine *engine) : Fighter(engine) { + _sequences.push_back(loadSequence("2002cr.seq")); + _sequences.push_back(loadSequence("2002cdl.seq")); + _sequences.push_back(loadSequence("2002cdr.seq")); + _sequences.push_back(loadSequence("2002cdm.seq")); + _sequences.push_back(loadSequence("2002lbk.seq")); +} + +void FighterPlayerAnna::handleAction(FightAction action) { + switch (action) { + default: + Fighter::handleAction(action); + return; + + case kFightAction1: + if ((_sequenceIndex != 1 && _sequenceIndex != 3) || checkFrame(4)) { + setSequenceAndDraw(4, kFightSequenceType1); + _opponent->setSequenceAndDraw(4, kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + update(); + } else { + _field_34++; + } + break; + + case kFightAction2: + if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) { + setSequenceAndDraw(4, kFightSequenceType1); + _opponent->setSequenceAndDraw(5, kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + update(); + } else { + _field_34++; + } + break; + + case kFightAction3: + if ((_sequenceIndex != 2 && _sequenceIndex != 1) || checkFrame(4)) { + setSequenceAndDraw(4, kFightSequenceType1); + _opponent->setSequenceAndDraw(6, kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + update(); + } else { + _field_34++; + } + break; + + case kFightAction128: + switch (_opponent->getSequenceIndex()) { + default: + setSequenceAndDraw(3, kFightSequenceType0); + break; + + case 1: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 2: + setSequenceAndDraw(3, kFightSequenceType0); + break; + + case 3: + setSequenceAndDraw(2, kFightSequenceType0); + break; + } + break; + } + + if (_field_34 > 4) { + getSoundQueue()->removeFromQueue(kEntityTables0); + _fight->bailout(Fight::kFightEndWin); + } +} + +////////////////////////////////////////////////////////////////////////// +// Opponent +////////////////////////////////////////////////////////////////////////// +FighterOpponentAnna::FighterOpponentAnna(LastExpressEngine *engine) : Opponent(engine) { + _sequences.push_back(loadSequence("2002or.seq")); + _sequences.push_back(loadSequence("2002oal.seq")); + _sequences.push_back(loadSequence("2002oam.seq")); + _sequences.push_back(loadSequence("2002oar.seq")); + _sequences.push_back(loadSequence("2002okr.seq")); + _sequences.push_back(loadSequence("2002okml.seq")); + _sequences.push_back(loadSequence("2002okm.seq")); + + getSound()->playSound(kEntityTables0, "MUS030", kFlagDefault); + + _field_38 = 30; +} + +void FighterOpponentAnna::update() { + if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) { + + if (_opponent->getField34() >= 2) { + switch (rnd(6)) { + default: + break; + + case 0: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 1: + setSequenceAndDraw(2, kFightSequenceType0); + break; + + case 2: + setSequenceAndDraw(3, kFightSequenceType0); + break; + + case 3: + setSequenceAndDraw(3, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + + case 4: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + + case 5: + setSequenceAndDraw(3, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + } + } + + // Update field_38 + _field_38 = (int32)rnd(15); + } + + if (_frame && checkFrame(2)) { + if (_sequenceIndex == 1 || _sequenceIndex == 2 || _sequenceIndex == 3) + _opponent->handleAction((FightAction)_sequenceIndex); + + if (_opponent->getCountdown() <= 0) { + getSoundQueue()->removeFromQueue(kEntityTables0); + handleAction(kFightActionLost); + } + } + + Fighter::update(); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/fight/fighter_anna.h b/engines/lastexpress/fight/fighter_anna.h new file mode 100644 index 0000000000..abb6f9dc64 --- /dev/null +++ b/engines/lastexpress/fight/fighter_anna.h @@ -0,0 +1,48 @@ +/* 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. + * + */ + +#ifndef LASTEXPRESS_FIGHTER_ANNA_H +#define LASTEXPRESS_FIGHTER_ANNA_H + +#include "lastexpress/fight/fighter.h" + +namespace LastExpress { + +class LastExpressEngine; + +class FighterPlayerAnna : public Fighter { +public: + FighterPlayerAnna(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); +}; + +class FighterOpponentAnna : public Opponent { +public: + FighterOpponentAnna(LastExpressEngine *engine); + + virtual void update(); +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_FIGHTER_ANNA_H diff --git a/engines/lastexpress/fight/fighter_ivo.cpp b/engines/lastexpress/fight/fighter_ivo.cpp new file mode 100644 index 0000000000..87a52c6be4 --- /dev/null +++ b/engines/lastexpress/fight/fighter_ivo.cpp @@ -0,0 +1,245 @@ +/* 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. + * + */ + +#include "lastexpress/fight/fighter_ivo.h" + +#include "lastexpress/data/sequence.h" + +#include "lastexpress/sound/queue.h" +#include "lastexpress/sound/sound.h" + +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" +#include "lastexpress/resource.h" + +namespace LastExpress { + +////////////////////////////////////////////////////////////////////////// +// Player +////////////////////////////////////////////////////////////////////////// +FighterPlayerIvo::FighterPlayerIvo(LastExpressEngine *engine) : Fighter(engine) { + _sequences.push_back(loadSequence("2003cr.seq")); + _sequences.push_back(loadSequence("2003car.seq")); + _sequences.push_back(loadSequence("2003cal.seq")); + _sequences.push_back(loadSequence("2003cdr.seq")); + _sequences.push_back(loadSequence("2003cdm.seq")); + _sequences.push_back(loadSequence("2003chr.seq")); + _sequences.push_back(loadSequence("2003chl.seq")); + _sequences.push_back(loadSequence("2003ckr.seq")); + _sequences.push_back(loadSequence("2003lbk.seq")); + _sequences.push_back(loadSequence("2003fbk.seq")); + + _countdown = 5; +} + +void FighterPlayerIvo::handleAction(FightAction action) { + switch (action) { + default: + Fighter::handleAction(action); + return; + + case kFightAction1: + if (_sequenceIndex != 1 || checkFrame(4)) { + setSequenceAndDraw(7, kFightSequenceType1); + _opponent->setSequenceAndDraw(4, kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + update(); + } + break; + + case kFightAction2: + if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) { + setSequenceAndDraw(7, kFightSequenceType1); + _opponent->setSequenceAndDraw(5, kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + update(); + } + break; + + case kFightAction128: + switch (_opponent->getSequenceIndex()) { + default: + case 1: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 2: + setSequenceAndDraw(2, kFightSequenceType0); + break; + } + break; + + case kFightAction129: + setSequenceAndDraw((_opponent->getCountdown() > 1) ? 4 : 3, _sequenceIndex ? kFightSequenceType2 : kFightSequenceType0); + break; + + case kFightAction130: + setSequenceAndDraw(3, _sequenceIndex ? kFightSequenceType2 : kFightSequenceType0); + break; + } +} + +void FighterPlayerIvo::update() { + + if ((_sequenceIndex == 3 || _sequenceIndex == 4) && !_frameIndex) + _opponent->handleAction(kFightAction131); + + if (_frame && checkFrame(2)) { + + // Draw sequences + if (_opponent->getCountdown() <= 0) { + setSequenceAndDraw(9, kFightSequenceType1); + _opponent->setSequenceAndDraw(8, kFightSequenceType1); + getSoundQueue()->removeFromQueue(kEntityTables0); + + handleAction(kFightActionWin); + return; + } + + if (_sequenceIndex == 3 || _sequenceIndex == 4) + _opponent->handleAction((FightAction)_sequenceIndex); + } + + Fighter::update(); +} + +bool FighterPlayerIvo::canInteract(FightAction action) { + if (action == kFightAction129 || action == kFightAction130) + return (_sequenceIndex >= 8); + + return Fighter::canInteract(); +} + +////////////////////////////////////////////////////////////////////////// +// Opponent +////////////////////////////////////////////////////////////////////////// +FighterOpponentIvo::FighterOpponentIvo(LastExpressEngine *engine) : Opponent(engine) { + _sequences.push_back(loadSequence("2003or.seq")); + _sequences.push_back(loadSequence("2003oal.seq")); + _sequences.push_back(loadSequence("2003oar.seq")); + _sequences.push_back(loadSequence("2003odm.seq")); + _sequences.push_back(loadSequence("2003okl.seq")); + _sequences.push_back(loadSequence("2003okj.seq")); + _sequences.push_back(loadSequence("blank.seq")); + _sequences.push_back(loadSequence("csdr.seq")); + _sequences.push_back(loadSequence("2003l.seq")); + + getSound()->playSound(kEntityTables0, "MUS032", kFlagDefault); + + _countdown = 5; + _field_38 = 15; +} + +void FighterOpponentIvo::handleAction(FightAction action) { + switch (action) { + default: + Fighter::handleAction(action); + break; + + case kFightAction3: + if ((_sequenceIndex != 1 && _sequenceIndex != 3) || checkFrame(4)) { + setSequenceAndDraw(6, kFightSequenceType1); + _opponent->setSequenceAndDraw(6, kFightSequenceType1); + _opponent->handleAction(kFightAction103); + } + break; + + case kFightAction4: + if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) { + setSequenceAndDraw(6, kFightSequenceType1); + _opponent->setSequenceAndDraw(5, kFightSequenceType1); + _opponent->handleAction(kFightAction103); + } + break; + + case kFightAction131: + if (_sequenceIndex) + break; + + if (rnd(100) <= (unsigned int)(_countdown > 2 ? 60 : 75)) { + setSequenceAndDraw(3 , kFightSequenceType1); + if (_opponent->getSequenceIndex() == 4) + setSequenceAndDraw(2, kFightSequenceType2); + } + break; + } +} + +void FighterOpponentIvo::update() { + if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) { + + if (_opponent->getField34() >= 2) { + switch (rnd(5)) { + default: + break; + + case 0: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 1: + setSequenceAndDraw(2, kFightSequenceType0); + break; + + case 2: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + + case 3: + setSequenceAndDraw(0, kFightSequenceType2); + setSequenceAndDraw(1, kFightSequenceType2); + break; + + case 4: + setSequenceAndDraw(0, kFightSequenceType1); + setSequenceAndDraw(1, kFightSequenceType2); + break; + } + } + + // Update field_38 + _field_38 = 3 * _countdown + (int32)rnd(10); + } + + if (_frame && checkFrame(2)) { + + if (_opponent->getCountdown() <= 0) { + setSequenceAndDraw(7, kFightSequenceType1); + _opponent->setSequenceAndDraw(8, kFightSequenceType1); + getSoundQueue()->removeFromQueue(kEntityTables0); + + _opponent->handleAction(kFightActionWin); + + return; + } + + if (_sequenceIndex == 1 || _sequenceIndex == 2) + _opponent->handleAction((FightAction)_sequenceIndex); + } + + Fighter::update(); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/fight/fighter_ivo.h b/engines/lastexpress/fight/fighter_ivo.h new file mode 100644 index 0000000000..ca54fea904 --- /dev/null +++ b/engines/lastexpress/fight/fighter_ivo.h @@ -0,0 +1,51 @@ +/* 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. + * + */ + +#ifndef LASTEXPRESS_FIGHTER_IVO_H +#define LASTEXPRESS_FIGHTER_IVO_H + +#include "lastexpress/fight/fighter.h" + +namespace LastExpress { + +class LastExpressEngine; + +class FighterPlayerIvo : public Fighter { +public: + FighterPlayerIvo(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); + virtual bool canInteract(FightAction action = kFightActionNone); +}; + +class FighterOpponentIvo : public Opponent { +public: + FighterOpponentIvo(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_FIGHTER_IVO_H diff --git a/engines/lastexpress/fight/fighter_milos.cpp b/engines/lastexpress/fight/fighter_milos.cpp new file mode 100644 index 0000000000..9f8e726165 --- /dev/null +++ b/engines/lastexpress/fight/fighter_milos.cpp @@ -0,0 +1,222 @@ +/* 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. + * + */ + +#include "lastexpress/fight/fighter_milos.h" + +#include "lastexpress/data/cursor.h" +#include "lastexpress/data/sequence.h" + +#include "lastexpress/sound/queue.h" +#include "lastexpress/sound/sound.h" + +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" +#include "lastexpress/resource.h" + +namespace LastExpress { + +////////////////////////////////////////////////////////////////////////// +// Player +////////////////////////////////////////////////////////////////////////// +FighterPlayerMilos::FighterPlayerMilos(LastExpressEngine *engine) : Fighter(engine) { + _sequences.push_back(loadSequence("2001cr.seq")); + _sequences.push_back(loadSequence("2001cdl.seq")); + _sequences.push_back(loadSequence("2001cdr.seq")); + _sequences.push_back(loadSequence("2001cdm.seq")); + _sequences.push_back(loadSequence("2001csgr.seq")); + _sequences.push_back(loadSequence("2001csgl.seq")); + _sequences.push_back(loadSequence("2001dbk.seq")); +} + +void FighterPlayerMilos::handleAction(FightAction action) { + switch (action) { + default: + Fighter::handleAction(action); + return; + + case kFightAction1: + if (_sequenceIndex != 1 || checkFrame(4)) { + setSequenceAndDraw(6, kFightSequenceType1); + _opponent->setSequenceAndDraw(3, kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + update(); + } else { + _field_34++; + } + break; + + case kFightAction2: + if ((_sequenceIndex != 2 && _sequenceIndex != 3) || checkFrame(4)) { + setSequenceAndDraw(6, kFightSequenceType1); + _opponent->setSequenceAndDraw(4, kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + update(); + } else { + _field_34++; + } + break; + + case kFightAction128: + if (_sequenceIndex != 1 || checkFrame(4) || _opponent->getSequenceIndex() != 1) { + switch (_opponent->getSequenceIndex()) { + default: + setSequenceAndDraw(rnd(3) + 1, kFightSequenceType0); + break; + + case 1: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 2: + setSequenceAndDraw(3, kFightSequenceType0); + break; + } + } else { + setSequenceAndDraw(4, kFightSequenceType1); + update(); + } + break; + } +} + +void FighterPlayerMilos::update() { + if (_frame && checkFrame(2)) { + + // Draw sequences + if (_opponent->getCountdown() <= 0) { + setSequenceAndDraw(5, kFightSequenceType1); + _opponent->setSequenceAndDraw(6, kFightSequenceType1); + + getSoundQueue()->removeFromQueue(kEntityTables0); + getSound()->playSound(kEntityTrain, "MUS029", kFlagDefault); + + handleAction(kFightActionWin); + } + + if (_sequenceIndex == 4) { + _opponent->handleAction(kFightAction4); + _fight->setEndType(Fight::kFightEndLost); + } + } + + Fighter::update(); +} + +bool FighterPlayerMilos::canInteract(FightAction action) { + if (action != kFightAction128 + || _sequenceIndex != 1 + || !_frame + || checkFrame(4) + || _opponent->getSequenceIndex() != 1) { + return Fighter::canInteract(); + } + + _engine->getCursor()->setStyle(kCursorHand); + + return true; +} + +////////////////////////////////////////////////////////////////////////// +// Opponent +////////////////////////////////////////////////////////////////////////// +FighterOpponentMilos::FighterOpponentMilos(LastExpressEngine *engine) : Opponent(engine) { + _sequences.push_back(loadSequence("2001or.seq")); + _sequences.push_back(loadSequence("2001oal.seq")); + _sequences.push_back(loadSequence("2001oam.seq")); + _sequences.push_back(loadSequence("2001okl.seq")); + _sequences.push_back(loadSequence("2001okm.seq")); + _sequences.push_back(loadSequence("2001dbk.seq")); + _sequences.push_back(loadSequence("2001wbk.seq")); + + getSound()->playSound(kEntityTables0, "MUS027", kFlagDefault); + + _field_38 = 35; +} + +void FighterOpponentMilos::handleAction(FightAction action) { + if (action == kFightAction4) { + setSequenceAndDraw(5, kFightSequenceType1); + _opponent->handleAction(kFightAction103); + } else { + if (action != kFightAction131) + Fighter::handleAction(action); + } +} + +void FighterOpponentMilos::update() { + if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) { + + if (_opponent->getField34() >= 2) { + switch (rnd(5)) { + default: + break; + + case 0: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 1: + setSequenceAndDraw(2, kFightSequenceType0); + break; + + case 2: + setSequenceAndDraw(2, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType1); + break; + + case 3: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + + case 4: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(1, kFightSequenceType2); + break; + } + } else { + setSequenceAndDraw(2, kFightSequenceType0); + } + + // Update field_38 + if (_opponent->getField34() < 5) + _field_38 = 6 * (5 - _opponent->getField34()); + else + _field_38 = 0; + } + + if (_frame && checkFrame(2)) { + if (_sequenceIndex == 1 || _sequenceIndex == 2) + _opponent->handleAction((FightAction)_sequenceIndex); + + if (_opponent->getCountdown() <= 0) { + getSoundQueue()->removeFromQueue(kEntityTables0); + handleAction(kFightActionLost); + } + } + + Fighter::update(); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/fight/fighter_milos.h b/engines/lastexpress/fight/fighter_milos.h new file mode 100644 index 0000000000..2126dd1838 --- /dev/null +++ b/engines/lastexpress/fight/fighter_milos.h @@ -0,0 +1,51 @@ +/* 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. + * + */ + +#ifndef LASTEXPRESS_FIGHTER_MILOS_H +#define LASTEXPRESS_FIGHTER_MILOS_H + +#include "lastexpress/fight/fighter.h" + +namespace LastExpress { + +class LastExpressEngine; + +class FighterPlayerMilos : public Fighter { +public: + FighterPlayerMilos(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); + virtual bool canInteract(FightAction action = kFightActionNone); +}; + +class FighterOpponentMilos : public Opponent { +public: + FighterOpponentMilos(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_FIGHTER_MILOS_H diff --git a/engines/lastexpress/fight/fighter_salko.cpp b/engines/lastexpress/fight/fighter_salko.cpp new file mode 100644 index 0000000000..1082674235 --- /dev/null +++ b/engines/lastexpress/fight/fighter_salko.cpp @@ -0,0 +1,202 @@ +/* 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. + * + */ + +#include "lastexpress/fight/fighter_salko.h" + +#include "lastexpress/data/cursor.h" +#include "lastexpress/data/sequence.h" + +#include "lastexpress/sound/queue.h" +#include "lastexpress/sound/sound.h" + +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" +#include "lastexpress/resource.h" + +namespace LastExpress { + +////////////////////////////////////////////////////////////////////////// +// Player +////////////////////////////////////////////////////////////////////////// +FighterPlayerSalko::FighterPlayerSalko(LastExpressEngine *engine) : Fighter(engine) { + _sequences.push_back(loadSequence("2004cr.seq")); + _sequences.push_back(loadSequence("2004cdr.seq")); + _sequences.push_back(loadSequence("2004chj.seq")); + _sequences.push_back(loadSequence("2004bk.seq")); + + _countdown = 2; +} + +void FighterPlayerSalko::handleAction(FightAction action) { + switch (action) { + default: + Fighter::handleAction(action); + return; + + case kFightAction1: + case kFightAction2: + if (_sequenceIndex != 1 && checkFrame(4)) { + _field_34 = 0; + + setSequenceAndDraw(3, kFightSequenceType1); + _opponent->setSequenceAndDraw((action == kFightAction1 ? 3 : 4), kFightSequenceType1); + + _opponent->handleAction(kFightAction103); + + if (action == kFightAction2) + _countdown= 0; + + update(); + } else { + _field_34++; + } + break; + + case kFightAction5: + if (_sequenceIndex != 3) { + _opponent->handleAction(kFightAction103); + update(); + } + break; + + case kFightAction128: + setSequenceAndDraw(1, kFightSequenceType0); + _field_34 = 0; + break; + + case kFightAction131: + setSequenceAndDraw(2, (_sequenceIndex ? kFightSequenceType2 : kFightSequenceType0)); + break; + } +} + +void FighterPlayerSalko::update() { + Fighter::update(); + + // The original doesn't check for currentSequence2 != NULL (might not happen when everything is working properly, but crashes with our current implementation) + if (_frame && checkFrame(2)) { + + if (_opponent->getCountdown() <= 0) { + getSoundQueue()->removeFromQueue(kEntityTables0); + _fight->bailout(Fight::kFightEndWin); + + return; + } + + if (_sequenceIndex == 2) + _opponent->handleAction(kFightAction2); + } +} + +bool FighterPlayerSalko::canInteract(FightAction action) { + if (action == kFightAction131) { + if (_sequenceIndex == 1) { + if (_opponent->getCountdown() <= 0) + _engine->getCursor()->setStyle(kCursorHand); + + return true; + } + + return false; + } + + return Fighter::canInteract(); +} + +////////////////////////////////////////////////////////////////////////// +// Opponent +////////////////////////////////////////////////////////////////////////// +FighterOpponentSalko::FighterOpponentSalko(LastExpressEngine *engine) : Opponent(engine) { + _sequences.push_back(loadSequence("2004or.seq")); + _sequences.push_back(loadSequence("2004oam.seq")); + _sequences.push_back(loadSequence("2004oar.seq")); + _sequences.push_back(loadSequence("2004okr.seq")); + _sequences.push_back(loadSequence("2004ohm.seq")); + _sequences.push_back(loadSequence("blank.seq")); + + getSound()->playSound(kEntityTables0, "MUS035", kFlagDefault); + + _countdown = 3; + _field_38 = 30; +} + +void FighterOpponentSalko::handleAction(FightAction action) { + if (action == kFightAction2) { + setSequenceAndDraw(5, kFightSequenceType1); + _opponent->handleAction(kFightAction103); + } else { + Fighter::handleAction(action); + } +} + +void FighterOpponentSalko::update() { + if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) { + + switch (rnd(5)) { + default: + break; + + case 0: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 1: + setSequenceAndDraw(2, kFightSequenceType0); + break; + + case 2: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + + case 3: + setSequenceAndDraw(2, kFightSequenceType0); + setSequenceAndDraw(1, kFightSequenceType2); + break; + + case 4: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(1, kFightSequenceType2); + break; + } + + // Update field_38 + _field_38 = 4 * _countdown; + } + + if (_frame && checkFrame(2)) { + if (_opponent->getCountdown() <= 0) { + getSoundQueue()->removeFromQueue(kEntityTables0); + _fight->bailout(Fight::kFightEndLost); + + // Stop processing + return; + } + + if (_sequenceIndex == 1 || _sequenceIndex == 2) + _opponent->handleAction((FightAction)_sequenceIndex); + } + + Fighter::update(); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/fight/fighter_salko.h b/engines/lastexpress/fight/fighter_salko.h new file mode 100644 index 0000000000..0a2a615867 --- /dev/null +++ b/engines/lastexpress/fight/fighter_salko.h @@ -0,0 +1,51 @@ +/* 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. + * + */ + +#ifndef LASTEXPRESS_FIGHTER_SALKO_H +#define LASTEXPRESS_FIGHTER_SALKO_H + +#include "lastexpress/fight/fighter.h" + +namespace LastExpress { + +class LastExpressEngine; + +class FighterPlayerSalko : public Fighter { +public: + FighterPlayerSalko(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); + virtual bool canInteract(FightAction action = kFightActionNone); +}; + +class FighterOpponentSalko : public Opponent { +public: + FighterOpponentSalko(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_FIGHTER_SALKO_H diff --git a/engines/lastexpress/fight/fighter_vesna.cpp b/engines/lastexpress/fight/fighter_vesna.cpp new file mode 100644 index 0000000000..02aaa1c16c --- /dev/null +++ b/engines/lastexpress/fight/fighter_vesna.cpp @@ -0,0 +1,265 @@ +/* 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. + * + */ + +#include "lastexpress/fight/fighter_vesna.h" + +#include "lastexpress/data/cursor.h" +#include "lastexpress/data/sequence.h" + +#include "lastexpress/sound/queue.h" +#include "lastexpress/sound/sound.h" + +#include "lastexpress/helpers.h" +#include "lastexpress/lastexpress.h" +#include "lastexpress/resource.h" + +namespace LastExpress { + +////////////////////////////////////////////////////////////////////////// +// Player +////////////////////////////////////////////////////////////////////////// +FighterPlayerVesna::FighterPlayerVesna(LastExpressEngine *engine) : Fighter(engine) { + _sequences.push_back(loadSequence("2005cr.seq")); + _sequences.push_back(loadSequence("2005cdr.seq")); + _sequences.push_back(loadSequence("2005cbr.seq")); + _sequences.push_back(loadSequence("2005bk.seq")); + _sequences.push_back(loadSequence("2005cdm1.seq")); + _sequences.push_back(loadSequence("2005chl.seq")); +} + +void FighterPlayerVesna::handleAction(FightAction action) { + switch (action) { + default: + Fighter::handleAction(action); + return; + + case kFightAction1: + if (_sequenceIndex != 1) { + _opponent->handleAction(kFightAction103); + update(); + } else { + _field_34++; + } + break; + + case kFightAction2: + if (_sequenceIndex != 2) { + _opponent->handleAction(kFightAction103); + update(); + } else { + _field_34++; + } + break; + + case kFightAction5: + if (_sequenceIndex != 3) { + _opponent->handleAction(kFightAction103); + update(); + } + break; + + case kFightAction128: + if (_sequenceIndex == 1 && _opponent->getSequenceIndex() == 1 && checkFrame(4)) { + setSequenceAndDraw(5, kFightSequenceType1); + } else { + setSequenceAndDraw((_opponent->getSequenceIndex() == 5) ? 3 : 1, kFightSequenceType0); + } + break; + + case kFightAction132: + setSequenceAndDraw(2, kFightSequenceType0); + break; + } + + if (_field_34 > 10) { + _opponent->setSequenceAndDraw(5, kFightSequenceType2); + _opponent->setCountdown(1); + _field_34 = 0; + } +} + +void FighterPlayerVesna::update() { + if (_frame && checkFrame(2)) { + + if (_sequenceIndex == 3) + _opponent->handleAction(kFightAction3); + + if (_opponent->getCountdown() <= 0) { + getSoundQueue()->removeFromQueue(kEntityTables0); + _fight->bailout(Fight::kFightEndWin); + return; + } + + if (_sequenceIndex == 5) + _opponent->handleAction(kFightAction5); + } + + Fighter::update(); +} + +bool FighterPlayerVesna::canInteract(FightAction action) { + if (action != kFightAction128) + return Fighter::canInteract(); + + if (_sequenceIndex != 1) { + + if (_opponent->getSequenceIndex() == 5) { + _engine->getCursor()->setStyle(kCursorDown); + return true; + } + + return Fighter::canInteract(); + } + + if (_opponent->getSequenceIndex() == 1 && checkFrame(4)) { + _engine->getCursor()->setStyle(kCursorPunchLeft); + return true; + } + + return false; +} + +////////////////////////////////////////////////////////////////////////// +// Opponent +////////////////////////////////////////////////////////////////////////// +FighterOpponentVesna::FighterOpponentVesna(LastExpressEngine *engine) : Opponent(engine) { + _sequences.push_back(loadSequence("2005or.seq")); + _sequences.push_back(loadSequence("2005oam.seq")); + _sequences.push_back(loadSequence("2005oar.seq")); + _sequences.push_back(loadSequence("2005okml.seq")); + _sequences.push_back(loadSequence("2005okr.seq")); + _sequences.push_back(loadSequence("2005odm1.seq")); + _sequences.push_back(loadSequence("2005csbm.seq")); + _sequences.push_back(loadSequence("2005oam4.seq")); + + getSound()->playSound(kEntityTables0, "MUS038", kFlagDefault); + + _countdown = 4; + _field_38 = 30; +} + +void FighterOpponentVesna::handleAction(FightAction action) { + switch (action) { + default: + Fighter::handleAction(action); + break; + + case kFightAction3: + _opponent->handleAction(kFightAction103); + break; + + case kFightAction5: + setSequenceAndDraw(7, kFightSequenceType1); + _opponent->handleAction(kFightAction103); + if (_countdown <= 1) + _countdown = 1; + break; + + case kFightAction131: + break; + } +} + +void FighterOpponentVesna::update() { + if (!_field_38 && canInteract(kFightAction1) && !_sequenceIndex2) { + + if (_opponent->getField34() == 1) { + setSequenceAndDraw(2, kFightSequenceType0); + } else { + switch (rnd(6)) { + default: + break; + + case 0: + setSequenceAndDraw(1, kFightSequenceType0); + break; + + case 1: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(1, kFightSequenceType2); + break; + + case 2: + setSequenceAndDraw(2, kFightSequenceType0); + break; + + case 3: + setSequenceAndDraw(2, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + + case 4: + setSequenceAndDraw(1, kFightSequenceType0); + setSequenceAndDraw(2, kFightSequenceType2); + break; + + case 5: + setSequenceAndDraw(2, kFightSequenceType0); + setSequenceAndDraw(1, kFightSequenceType2); + break; + } + } + + // Update field_38 + _field_38 = 4 * _countdown; + } + + if (_frame && checkFrame(2)) { + if (_sequenceIndex == 1 || _sequenceIndex == 2 || _sequenceIndex == 5) + _opponent->handleAction((FightAction)_sequenceIndex); + + if (_opponent->getCountdown() <= 0) { + + switch (_sequenceIndex) { + default: + break; + + case 1: + setSequenceAndDraw(3, kFightSequenceType1); + break; + + case 2: + setSequenceAndDraw(4, kFightSequenceType1); + break; + + case 5: + setSequenceAndDraw(6, kFightSequenceType1); + break; + } + + _opponent->setSequenceAndDraw(4, kFightSequenceType1); + + handleAction(kFightActionLost); + _opponent->update(); + Fighter::update(); + + getSoundQueue()->removeFromQueue(kEntityTables0); + + // Stop processing + return; + } + } + + Fighter::update(); +} + +} // End of namespace LastExpress diff --git a/engines/lastexpress/fight/fighter_vesna.h b/engines/lastexpress/fight/fighter_vesna.h new file mode 100644 index 0000000000..5c8ec855ae --- /dev/null +++ b/engines/lastexpress/fight/fighter_vesna.h @@ -0,0 +1,51 @@ +/* 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. + * + */ + +#ifndef LASTEXPRESS_FIGHTER_VESNA_H +#define LASTEXPRESS_FIGHTER_VESNA_H + +#include "lastexpress/fight/fighter.h" + +namespace LastExpress { + +class LastExpressEngine; + +class FighterPlayerVesna : public Fighter { +public: + FighterPlayerVesna(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); + virtual bool canInteract(FightAction action = kFightActionNone); +}; + +class FighterOpponentVesna : public Opponent { +public: + FighterOpponentVesna(LastExpressEngine *engine); + + virtual void handleAction(FightAction action); + virtual void update(); +}; + +} // End of namespace LastExpress + +#endif // LASTEXPRESS_FIGHTER_VESNA_H |