2010-10-18 19:17:38 +00:00
/* 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 .
*
* $ URL $
* $ Id $
*
*/
# include "lastexpress/game/fight.h"
# include "lastexpress/data/cursor.h"
# include "lastexpress/data/scene.h"
# include "lastexpress/data/sequence.h"
# include "lastexpress/game/entities.h"
# include "lastexpress/game/inventory.h"
# include "lastexpress/game/logic.h"
# include "lastexpress/game/object.h"
# include "lastexpress/game/scenes.h"
# include "lastexpress/game/sound.h"
# include "lastexpress/game/state.h"
# include "lastexpress/graphics.h"
# include "lastexpress/helpers.h"
# include "lastexpress/lastexpress.h"
# include "lastexpress/resource.h"
# include "common/func.h"
namespace LastExpress {
# define CALL_FUNCTION0(fighter, name) \
( * fighter - > name ) ( fighter )
# define CALL_FUNCTION1(fighter, name, a) \
( * fighter - > name ) ( fighter , a )
# define REGISTER_PLAYER_FUNCTIONS(name) \
if ( ! _data ) \
error ( " Fight::load##namePlayer - invalid data! " ) ; \
_data - > player - > handleAction = new Common : : Functor2Mem < Fighter * , FightAction , void , Fight > ( this , & Fight : : handleAction # # name ) ; \
_data - > player - > update = new Common : : Functor1Mem < Fighter * , void , Fight > ( this , & Fight : : update # # name ) ; \
_data - > player - > canInteract = new Common : : Functor2Mem < Fighter const * , FightAction , bool , Fight > ( this , & Fight : : canInteract # # name ) ;
# define REGISTER_OPPONENT_FUNCTIONS(name) \
if ( ! _data ) \
error ( " Fight::load##nameOpponent - invalid data! " ) ; \
_data - > opponent - > handleAction = new Common : : Functor2Mem < Fighter * , FightAction , void , Fight > ( this , & Fight : : handleOpponentAction # # name ) ; \
_data - > opponent - > update = new Common : : Functor1Mem < Fighter * , void , Fight > ( this , & Fight : : updateOpponent # # name ) ; \
_data - > opponent - > canInteract = new Common : : Functor2Mem < Fighter const * , FightAction , bool , Fight > ( this , & Fight : : canInteract ) ;
# define CHECK_SEQUENCE2(fighter, value) \
( fighter - > frame - > getInfo ( ) - > field_33 & value )
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 ) {
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
setStopped ( ) ;
getGlobalTimer ( ) ? _state = 0 : + + _state ;
getFlags ( ) - > mouseRightClick = true ;
}
if ( _handleTimer ) {
// Timer expired => show with full brightness
if ( ! getGlobalTimer ( ) )
getInventory ( ) - > drawEgg ( ) ;
_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 ( CALL_FUNCTION1 ( _data - > player , canInteract , ( FightAction ) hotspot - > action ) ) {
if ( ev . type = = Common : : EVENT_LBUTTONUP )
CALL_FUNCTION1 ( _data - > player , handleAction , ( 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 ( ) - > drawEgg ( ) ;
_handleTimer = true ;
}
// Stop fight if clicked
if ( ev . type = = Common : : EVENT_LBUTTONUP ) {
_handleTimer = false ;
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
bailout ( kFightEndExit ) ;
}
// Reset timer on right click
if ( ev . type = = Common : : EVENT_RBUTTONUP ) {
if ( getGlobalTimer ( ) ) {
if ( getSound ( ) - > isBuffered ( " TIMER " ) )
getSound ( ) - > 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::handleMouseMove - egg blinking not implemented! " ) ;
}
if ( ! _data | | _data - > index )
return ;
SceneHotspot * hotspot = NULL ;
if ( ! getScenes ( ) - > get ( getState ( ) - > scene ) - > checkHotSpot ( ev . mouse , & hotspot ) | | ! CALL_FUNCTION1 ( _data - > player , canInteract , ( FightAction ) hotspot - > action ) ) {
_engine - > getCursor ( ) - > setStyle ( kCursorNormal ) ;
} else {
_engine - > getCursor ( ) - > setStyle ( ( CursorStyle ) hotspot - > cursor ) ;
}
CALL_FUNCTION0 ( _data - > player , update ) ;
CALL_FUNCTION0 ( _data - > opponent , update ) ;
// Draw sequences
if ( ! _data - > isRunning )
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 - > isRunning ) {
if ( _engine - > handleEvents ( ) )
continue ;
getSound ( ) - > updateQueue ( ) ;
}
// Cleanup after fight is over
clearData ( ) ;
return _endType ;
}
//////////////////////////////////////////////////////////////////////////
// Status
//////////////////////////////////////////////////////////////////////////
void Fight : : setStopped ( ) {
if ( _data )
_data - > isRunning = false ;
}
void Fight : : bailout ( FightEndType type ) {
_state = 0 ;
_endType = type ;
setStopped ( ) ;
}
//////////////////////////////////////////////////////////////////////////
// Cleanup
//////////////////////////////////////////////////////////////////////////
void Fight : : clearData ( ) {
if ( ! _data )
return ;
// Clear data
clearSequences ( _data - > player ) ;
clearSequences ( _data - > opponent ) ;
2010-11-11 14:19:44 +00:00
SAFE_DELETE ( _data - > player ) ;
SAFE_DELETE ( _data - > opponent ) ;
2010-10-18 19:17:38 +00:00
2010-11-11 14:19:44 +00:00
SAFE_DELETE ( _data ) ;
2010-10-18 19:17:38 +00:00
_engine - > restoreEventHandlers ( ) ;
}
void Fight : : clearSequences ( Fighter * combatant ) const {
if ( ! combatant )
return ;
// The original game resets the function pointers to default values, just before deleting the struct
getScenes ( ) - > removeAndRedraw ( & combatant - > frame , false ) ;
// Free sequences
for ( int i = 0 ; i < ( int ) combatant - > sequences . size ( ) ; i + + )
2010-11-11 14:19:44 +00:00
SAFE_DELETE ( combatant - > sequences [ i ] ) ;
2010-10-18 19:17:38 +00:00
}
//////////////////////////////////////////////////////////////////////////
// Drawing
//////////////////////////////////////////////////////////////////////////
void Fight : : setSequenceAndDraw ( Fighter * combatant , uint32 sequenceIndex , FightSequenceType type ) const {
if ( combatant - > sequences . size ( ) < sequenceIndex )
return ;
switch ( type ) {
default :
break ;
case kFightSequenceType0 :
if ( combatant - > sequenceIndex )
return ;
combatant - > sequence = combatant - > sequences [ sequenceIndex ] ;
combatant - > sequenceIndex = sequenceIndex ;
draw ( combatant ) ;
break ;
case kFightSequenceType1 :
combatant - > sequence = combatant - > sequences [ sequenceIndex ] ;
combatant - > sequenceIndex = sequenceIndex ;
combatant - > sequenceIndex2 = 0 ;
draw ( combatant ) ;
break ;
case kFightSequenceType2 :
combatant - > sequenceIndex2 = sequenceIndex ;
break ;
}
}
void Fight : : draw ( Fighter * combatant ) const {
getScenes ( ) - > removeAndRedraw ( & combatant - > frame , false ) ;
combatant - > frameIndex = 0 ;
combatant - > field_24 = 0 ;
}
//////////////////////////////////////////////////////////////////////////
// Loading
//////////////////////////////////////////////////////////////////////////
void Fight : : loadData ( FightType type ) {
if ( ! _data )
error ( " Fight::loadData - invalid data! " ) ;
switch ( type ) {
default :
break ;
case kFightMilos :
loadMilosPlayer ( ) ;
loadMilosOpponent ( ) ;
break ;
case kFightAnna :
loadAnnaPlayer ( ) ;
loadAnnaOpponent ( ) ;
break ;
case kFightIvo :
loadIvoPlayer ( ) ;
loadIvoOpponent ( ) ;
break ;
case kFightSalko :
loadSalkoPlayer ( ) ;
loadSalkoOpponent ( ) ;
break ;
case kFightVesna :
loadVesnaPlayer ( ) ;
loadVesnaOpponent ( ) ;
break ;
}
if ( ! _data - > player | | ! _data - > opponent )
error ( " Fight::loadData - error loading fight data (type=%d) " , type ) ;
//////////////////////////////////////////////////////////////////////////
// Start running the fight
_data - > isRunning = true ;
if ( _state < 5 ) {
setSequenceAndDraw ( _data - > player , 0 , kFightSequenceType0 ) ;
setSequenceAndDraw ( _data - > opponent , 0 , kFightSequenceType0 ) ;
goto end_load ;
}
switch ( type ) {
default :
break ;
case kFightMilos :
_data - > opponent - > countdown = 1 ;
setSequenceAndDraw ( _data - > player , 4 , kFightSequenceType0 ) ;
setSequenceAndDraw ( _data - > opponent , 0 , kFightSequenceType0 ) ;
break ;
case kFightIvo :
_data - > opponent - > countdown = 1 ;
setSequenceAndDraw ( _data - > player , 3 , kFightSequenceType0 ) ;
setSequenceAndDraw ( _data - > opponent , 6 , kFightSequenceType0 ) ;
break ;
case kFightVesna :
_data - > opponent - > countdown = 1 ;
setSequenceAndDraw ( _data - > player , 0 , kFightSequenceType0 ) ;
setSequenceAndDraw ( _data - > player , 3 , kFightSequenceType2 ) ;
setSequenceAndDraw ( _data - > opponent , 5 , kFightSequenceType0 ) ;
break ;
}
end_load :
// Setup event handlers
_engine - > backupEventHandlers ( ) ;
SET_EVENT_HANDLERS ( Fight , this ) ;
}
//////////////////////////////////////////////////////////////////////////
// Shared
//////////////////////////////////////////////////////////////////////////
void Fight : : processFighter ( Fighter * fighter ) {
if ( ! _data )
error ( " Fight::processFighter - invalid data! " ) ;
if ( ! fighter - > sequence ) {
if ( fighter - > frame ) {
getScenes ( ) - > removeFromQueue ( fighter - > frame ) ;
getScenes ( ) - > setCoordinates ( fighter - > frame ) ;
}
SAFE_DELETE ( fighter - > frame ) ;
return ;
}
if ( fighter - > sequence - > count ( ) < = fighter - > frameIndex ) {
switch ( fighter - > action ) {
default :
break ;
case kFightAction101 :
setSequenceAndDraw ( fighter , fighter - > sequenceIndex2 , kFightSequenceType1 ) ;
fighter - > sequenceIndex2 = 0 ;
break ;
case kFightActionResetFrame :
fighter - > frameIndex = 0 ;
break ;
case kFightAction103 :
setSequenceAndDraw ( fighter , 0 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter , handleAction , kFightAction101 ) ;
setSequenceAndDraw ( fighter - > opponent , 0 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction101 ) ;
CALL_FUNCTION0 ( fighter - > opponent , update ) ;
break ;
case kFightActionWin :
bailout ( kFightEndWin ) ;
break ;
case kFightActionLost :
bailout ( kFightEndLost ) ;
break ;
}
}
if ( _data - > isRunning ) {
// Get the current sequence frame
SequenceFrame * frame = new SequenceFrame ( fighter - > sequence , ( uint16 ) fighter - > frameIndex ) ;
frame - > getInfo ( ) - > location = 1 ;
if ( fighter - > frame = = frame ) {
delete frame ;
return ;
}
getSound ( ) - > playFightSound ( frame - > getInfo ( ) - > soundAction , frame - > getInfo ( ) - > field_31 ) ;
// Add current frame to queue and advance
getScenes ( ) - > addToQueue ( frame ) ;
fighter - > frameIndex + + ;
if ( fighter - > frame ) {
getScenes ( ) - > removeFromQueue ( fighter - > frame ) ;
if ( ! frame - > getInfo ( ) - > field_2E )
getScenes ( ) - > setCoordinates ( fighter - > frame ) ;
}
// Replace by new frame
delete fighter - > frame ;
fighter - > frame = frame ;
}
}
void Fight : : handleAction ( Fighter * fighter , FightAction action ) {
switch ( action ) {
default :
return ;
case kFightAction101 :
break ;
case kFightActionResetFrame :
fighter - > countdown - - ;
break ;
case kFightAction103 :
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightActionResetFrame ) ;
break ;
case kFightActionWin :
_endType = kFightEndWin ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightActionResetFrame ) ;
break ;
case kFightActionLost :
_endType = kFightEndLost ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightActionResetFrame ) ;
break ;
}
// Update action
fighter - > action = action ;
}
bool Fight : : canInteract ( Fighter const * fighter , FightAction /*= (FightAction)0*/ ) {
return ( fighter - > action = = kFightAction101 & & ! fighter - > sequenceIndex ) ;
}
void Fight : : update ( Fighter * fighter ) {
processFighter ( fighter ) ;
if ( fighter - > frame )
fighter - > frame - > getInfo ( ) - > location = ( fighter - > action = = kFightActionResetFrame ? 2 : 0 ) ;
}
void Fight : : updateOpponent ( Fighter * fighter ) {
// This is an opponent struct!
Opponent * opponent = ( Opponent * ) fighter ;
processFighter ( opponent ) ;
if ( opponent - > field_38 & & ! opponent - > sequenceIndex )
opponent - > field_38 - - ;
if ( fighter - > frame )
fighter - > frame - > getInfo ( ) - > location = 1 ;
}
//////////////////////////////////////////////////////////////////////////
// Milos
//////////////////////////////////////////////////////////////////////////
void Fight : : loadMilosPlayer ( ) {
REGISTER_PLAYER_FUNCTIONS ( Milos )
_data - > player - > sequences . push_back ( loadSequence ( " 2001cr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2001cdl.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2001cdr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2001cdm.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2001csgr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2001csgl.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2001dbk.seq " ) ) ;
}
void Fight : : loadMilosOpponent ( ) {
REGISTER_OPPONENT_FUNCTIONS ( Milos )
_data - > opponent - > sequences . push_back ( loadSequence ( " 2001or.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2001oal.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2001oam.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2001okl.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2001okm.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2001dbk.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2001wbk.seq " ) ) ;
getSound ( ) - > playSound ( kEntityTables0 , " MUS027 " , SoundManager : : kFlagDefault ) ;
_data - > opponent - > field_38 = 35 ;
}
void Fight : : handleActionMilos ( Fighter * fighter , FightAction action ) {
switch ( action ) {
default :
handleAction ( fighter , action ) ;
return ;
case kFightAction1 :
if ( fighter - > sequenceIndex ! = 1 | | CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 6 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 3 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction2 :
if ( ( fighter - > sequenceIndex ! = 2 & & fighter - > sequenceIndex ! = 3 ) | | CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 6 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 4 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction128 :
if ( fighter - > sequenceIndex ! = 1 | | CHECK_SEQUENCE2 ( fighter , 4 ) | | fighter - > opponent - > sequenceIndex ! = 1 ) {
switch ( fighter - > opponent - > sequenceIndex ) {
default :
setSequenceAndDraw ( fighter , rnd ( 3 ) + 1 , kFightSequenceType0 ) ;
break ;
case 1 :
setSequenceAndDraw ( fighter , 1 , kFightSequenceType0 ) ;
break ;
case 2 :
setSequenceAndDraw ( fighter , 3 , kFightSequenceType0 ) ;
break ;
}
} else {
setSequenceAndDraw ( fighter , 4 , kFightSequenceType1 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
}
break ;
}
}
void Fight : : updateMilos ( Fighter * fighter ) {
if ( fighter - > frame & & CHECK_SEQUENCE2 ( fighter , 2 ) ) {
// Draw sequences
if ( fighter - > opponent - > countdown < = 0 ) {
setSequenceAndDraw ( fighter , 5 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 6 , kFightSequenceType1 ) ;
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
getSound ( ) - > playSound ( kEntityTrain , " MUS029 " , SoundManager : : kFlagDefault ) ;
CALL_FUNCTION1 ( fighter , handleAction , kFightActionWin ) ;
}
if ( fighter - > sequenceIndex = = 4 ) {
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction4 ) ;
_endType = kFightEndLost ;
}
}
update ( fighter ) ;
}
bool Fight : : canInteractMilos ( Fighter const * fighter , FightAction action ) {
if ( ! _data )
error ( " Fight::canInteractMilos - invalid data! " ) ;
if ( action ! = kFightAction128
| | _data - > player - > sequenceIndex ! = 1
| | ! fighter - > frame
| | CHECK_SEQUENCE2 ( fighter , 4 )
| | fighter - > opponent - > sequenceIndex ! = 1 ) {
return canInteract ( fighter ) ;
}
_engine - > getCursor ( ) - > setStyle ( kCursorHand ) ;
return true ;
}
void Fight : : handleOpponentActionMilos ( Fighter * fighter , FightAction action ) {
if ( action = = kFightAction4 ) {
setSequenceAndDraw ( fighter , 5 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
} else {
if ( action ! = kFightAction131 )
handleAction ( fighter , action ) ;
}
}
void Fight : : updateOpponentMilos ( Fighter * fighter ) {
// This is an opponent struct!
Opponent * opponent = ( Opponent * ) fighter ;
if ( ! opponent - > field_38 & & CALL_FUNCTION1 ( opponent , canInteract , kFightAction1 ) & & ! opponent - > sequenceIndex2 ) {
if ( opponent - > opponent - > field_34 > = 2 ) {
switch ( rnd ( 5 ) ) {
default :
break ;
case 0 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
break ;
case 1 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
break ;
case 2 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType1 ) ;
break ;
case 3 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
case 4 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 1 , kFightSequenceType2 ) ;
break ;
}
} else {
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
}
// Update field_38
if ( opponent - > opponent - > field_34 < 5 )
opponent - > field_38 = 6 * ( 5 - opponent - > opponent - > field_34 ) ;
else
opponent - > field_38 = 0 ;
}
if ( opponent - > frame & & CHECK_SEQUENCE2 ( opponent , 2 ) ) {
if ( opponent - > sequenceIndex = = 1 | | opponent - > sequenceIndex = = 2 )
CALL_FUNCTION1 ( opponent - > opponent , handleAction , ( FightAction ) opponent - > sequenceIndex ) ;
if ( opponent - > opponent - > countdown < = 0 ) {
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
CALL_FUNCTION1 ( opponent , handleAction , kFightActionLost ) ;
}
}
updateOpponent ( opponent ) ;
}
//////////////////////////////////////////////////////////////////////////
// Anna
//////////////////////////////////////////////////////////////////////////
void Fight : : loadAnnaPlayer ( ) {
if ( ! _data )
error ( " Fight::loadAnnaPlayer - invalid data! " ) ;
// Special case: we are using some shared functions directly
_data - > player - > handleAction = new Common : : Functor2Mem < Fighter * , FightAction , void , Fight > ( this , & Fight : : handleActionAnna ) ;
_data - > player - > update = new Common : : Functor1Mem < Fighter * , void , Fight > ( this , & Fight : : update ) ;
_data - > player - > canInteract = new Common : : Functor2Mem < Fighter const * , FightAction , bool , Fight > ( this , & Fight : : canInteract ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2002cr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2002cdl.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2002cdr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2002cdm.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2002lbk.seq " ) ) ;
}
void Fight : : loadAnnaOpponent ( ) {
if ( ! _data )
error ( " Fight::loadAnnaOpponent - invalid data! " ) ;
// Special case: we are using some shared functions directly
_data - > opponent - > handleAction = new Common : : Functor2Mem < Fighter * , FightAction , void , Fight > ( this , & Fight : : handleAction ) ;
_data - > opponent - > update = new Common : : Functor1Mem < Fighter * , void , Fight > ( this , & Fight : : updateOpponentAnna ) ;
_data - > opponent - > canInteract = new Common : : Functor2Mem < Fighter const * , FightAction , bool , Fight > ( this , & Fight : : canInteract ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2002or.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2002oal.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2002oam.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2002oar.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2002okr.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2002okml.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2002okm.seq " ) ) ;
getSound ( ) - > playSound ( kEntityTables0 , " MUS030 " , SoundManager : : kFlagDefault ) ;
_data - > opponent - > field_38 = 30 ;
}
void Fight : : handleActionAnna ( Fighter * fighter , FightAction action ) {
switch ( action ) {
default :
handleAction ( fighter , action ) ;
return ;
case kFightAction1 :
if ( ( fighter - > sequenceIndex ! = 1 & & fighter - > sequenceIndex ! = 3 ) | | CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 4 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 4 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction2 :
if ( ( fighter - > sequenceIndex ! = 2 & & fighter - > sequenceIndex ! = 3 ) | | CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 4 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 5 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction3 :
if ( ( fighter - > sequenceIndex ! = 2 & & fighter - > sequenceIndex ! = 1 ) | | CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 4 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 6 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction128 :
switch ( fighter - > opponent - > sequenceIndex ) {
default :
setSequenceAndDraw ( fighter , 3 , kFightSequenceType0 ) ;
break ;
case 1 :
setSequenceAndDraw ( fighter , 1 , kFightSequenceType0 ) ;
break ;
case 2 :
setSequenceAndDraw ( fighter , 3 , kFightSequenceType0 ) ;
break ;
case 3 :
setSequenceAndDraw ( fighter , 2 , kFightSequenceType0 ) ;
break ;
}
break ;
}
if ( fighter - > field_34 > 4 ) {
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
bailout ( kFightEndWin ) ;
}
}
void Fight : : updateOpponentAnna ( Fighter * fighter ) {
// This is an opponent struct!
Opponent * opponent = ( Opponent * ) fighter ;
if ( ! opponent - > field_38 & & CALL_FUNCTION1 ( opponent , canInteract , kFightAction1 ) & & ! opponent - > sequenceIndex2 ) {
if ( opponent - > opponent - > field_34 > = 2 ) {
switch ( rnd ( 6 ) ) {
default :
break ;
case 0 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
break ;
case 1 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
break ;
case 2 :
setSequenceAndDraw ( opponent , 3 , kFightSequenceType0 ) ;
break ;
case 3 :
setSequenceAndDraw ( opponent , 3 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
case 4 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
case 5 :
setSequenceAndDraw ( opponent , 3 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
}
}
// Update field_38
opponent - > field_38 = ( int32 ) rnd ( 15 ) ;
}
if ( opponent - > frame & & CHECK_SEQUENCE2 ( opponent , 2 ) ) {
if ( opponent - > sequenceIndex = = 1 | | opponent - > sequenceIndex = = 2 | | opponent - > sequenceIndex = = 3 )
CALL_FUNCTION1 ( opponent - > opponent , handleAction , ( FightAction ) opponent - > sequenceIndex ) ;
if ( opponent - > opponent - > countdown < = 0 ) {
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
CALL_FUNCTION1 ( opponent , handleAction , kFightActionLost ) ;
}
}
updateOpponent ( opponent ) ;
}
//////////////////////////////////////////////////////////////////////////
// Ivo
//////////////////////////////////////////////////////////////////////////
void Fight : : loadIvoPlayer ( ) {
REGISTER_PLAYER_FUNCTIONS ( Ivo )
_data - > player - > sequences . push_back ( loadSequence ( " 2003cr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003car.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003cal.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003cdr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003cdm.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003chr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003chl.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003ckr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003lbk.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2003fbk.seq " ) ) ;
_data - > player - > countdown = 5 ;
}
void Fight : : loadIvoOpponent ( ) {
REGISTER_OPPONENT_FUNCTIONS ( Ivo )
_data - > opponent - > sequences . push_back ( loadSequence ( " 2003or.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2003oal.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2003oar.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2003odm.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2003okl.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2003okj.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " blank.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " csdr.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2003l.seq " ) ) ;
getSound ( ) - > playSound ( kEntityTables0 , " MUS032 " , SoundManager : : kFlagDefault ) ;
_data - > opponent - > countdown = 5 ;
_data - > opponent - > field_38 = 15 ;
}
void Fight : : handleActionIvo ( Fighter * fighter , FightAction action ) {
switch ( action ) {
default :
handleAction ( fighter , action ) ;
return ;
case kFightAction1 :
if ( fighter - > sequenceIndex ! = 1 | | CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 7 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 4 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
}
break ;
case kFightAction2 :
if ( ( fighter - > sequenceIndex ! = 2 & & fighter - > sequenceIndex ! = 3 ) | | CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 7 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 5 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
}
break ;
case kFightAction128 :
switch ( fighter - > opponent - > sequenceIndex ) {
default :
case 1 :
setSequenceAndDraw ( fighter , 1 , kFightSequenceType0 ) ;
break ;
case 2 :
setSequenceAndDraw ( fighter , 2 , kFightSequenceType0 ) ;
break ;
}
break ;
case kFightAction129 :
setSequenceAndDraw ( fighter , ( fighter - > opponent - > countdown > 1 ) ? 4 : 3 , fighter - > sequenceIndex ? kFightSequenceType2 : kFightSequenceType0 ) ;
break ;
case kFightAction130 :
setSequenceAndDraw ( fighter , 3 , fighter - > sequenceIndex ? kFightSequenceType2 : kFightSequenceType0 ) ;
break ;
}
}
void Fight : : updateIvo ( Fighter * fighter ) {
if ( ( fighter - > sequenceIndex = = 3 | | fighter - > sequenceIndex = = 4 ) & & ! fighter - > frameIndex )
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction131 ) ;
if ( fighter - > frame & & CHECK_SEQUENCE2 ( fighter , 2 ) ) {
// Draw sequences
if ( fighter - > opponent - > countdown < = 0 ) {
setSequenceAndDraw ( fighter , 9 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , 8 , kFightSequenceType1 ) ;
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
CALL_FUNCTION1 ( fighter , handleAction , kFightActionWin ) ;
return ;
}
if ( fighter - > sequenceIndex = = 3 | | fighter - > sequenceIndex = = 4 )
CALL_FUNCTION1 ( fighter - > opponent , handleAction , ( FightAction ) fighter - > sequenceIndex ) ;
}
update ( fighter ) ;
}
bool Fight : : canInteractIvo ( Fighter const * fighter , FightAction action ) {
if ( action = = kFightAction129 | | action = = kFightAction130 )
return ( fighter - > sequenceIndex > = 8 ) ;
return canInteract ( fighter ) ;
}
void Fight : : handleOpponentActionIvo ( Fighter * fighter , FightAction action ) {
// This is an opponent struct!
Opponent * opponent = ( Opponent * ) fighter ;
switch ( action ) {
default :
handleAction ( fighter , action ) ;
break ;
case kFightAction3 :
if ( ( opponent - > sequenceIndex ! = 1 & & opponent - > sequenceIndex ! = 3 ) | | CHECK_SEQUENCE2 ( opponent , 4 ) ) {
setSequenceAndDraw ( opponent , 6 , kFightSequenceType1 ) ;
setSequenceAndDraw ( opponent - > opponent , 6 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( opponent - > opponent , handleAction , kFightAction103 ) ;
}
break ;
case kFightAction4 :
if ( ( opponent - > sequenceIndex ! = 2 & & opponent - > sequenceIndex ! = 3 ) | | CHECK_SEQUENCE2 ( opponent , 4 ) ) {
setSequenceAndDraw ( opponent , 6 , kFightSequenceType1 ) ;
setSequenceAndDraw ( opponent - > opponent , 5 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( opponent - > opponent , handleAction , kFightAction103 ) ;
}
break ;
case kFightAction131 :
if ( opponent - > sequenceIndex )
break ;
if ( rnd ( 100 ) < = ( unsigned int ) ( opponent - > countdown > 2 ? 60 : 75 ) ) {
setSequenceAndDraw ( opponent , 3 , kFightSequenceType1 ) ;
if ( opponent - > opponent - > sequenceIndex = = 4 )
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
}
break ;
}
}
void Fight : : updateOpponentIvo ( Fighter * fighter ) {
// This is an opponent struct!
Opponent * opponent = ( Opponent * ) fighter ;
if ( ! opponent - > field_38 & & CALL_FUNCTION1 ( opponent , canInteract , kFightAction1 ) & & ! opponent - > sequenceIndex2 ) {
if ( opponent - > opponent - > field_34 > = 2 ) {
switch ( rnd ( 5 ) ) {
default :
break ;
case 0 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
break ;
case 1 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
break ;
case 2 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
case 3 :
setSequenceAndDraw ( opponent , 0 , kFightSequenceType2 ) ;
setSequenceAndDraw ( opponent , 1 , kFightSequenceType2 ) ;
break ;
case 4 :
setSequenceAndDraw ( opponent , 0 , kFightSequenceType1 ) ;
setSequenceAndDraw ( opponent , 1 , kFightSequenceType2 ) ;
break ;
}
}
// Update field_38
opponent - > field_38 = 3 * opponent - > countdown + ( int32 ) rnd ( 10 ) ;
}
if ( opponent - > frame & & CHECK_SEQUENCE2 ( opponent , 2 ) ) {
if ( opponent - > opponent - > countdown < = 0 ) {
setSequenceAndDraw ( opponent , 7 , kFightSequenceType1 ) ;
setSequenceAndDraw ( opponent - > opponent , 8 , kFightSequenceType1 ) ;
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
CALL_FUNCTION1 ( opponent - > opponent , handleAction , kFightActionWin ) ;
return ;
}
if ( opponent - > sequenceIndex = = 1 | | opponent - > sequenceIndex = = 2 )
CALL_FUNCTION1 ( opponent - > opponent , handleAction , ( FightAction ) opponent - > sequenceIndex ) ;
}
updateOpponent ( opponent ) ;
}
//////////////////////////////////////////////////////////////////////////
// Salko
//////////////////////////////////////////////////////////////////////////
void Fight : : loadSalkoPlayer ( ) {
REGISTER_PLAYER_FUNCTIONS ( Salko )
_data - > player - > sequences . push_back ( loadSequence ( " 2004cr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2004cdr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2004chj.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2004bk.seq " ) ) ;
_data - > player - > countdown = 2 ;
}
void Fight : : loadSalkoOpponent ( ) {
REGISTER_OPPONENT_FUNCTIONS ( Salko )
_data - > opponent - > sequences . push_back ( loadSequence ( " 2004or.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2004oam.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2004oar.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2004okr.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2004ohm.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " blank.seq " ) ) ;
getSound ( ) - > playSound ( kEntityTables0 , " MUS035 " , SoundManager : : kFlagDefault ) ;
_data - > opponent - > countdown = 3 ;
_data - > opponent - > field_38 = 30 ;
}
void Fight : : handleActionSalko ( Fighter * fighter , FightAction action ) {
switch ( action ) {
default :
handleAction ( fighter , action ) ;
return ;
case kFightAction1 :
case kFightAction2 :
if ( fighter - > sequenceIndex ! = 1 & & CHECK_SEQUENCE2 ( fighter , 4 ) ) {
fighter - > field_34 = 0 ;
setSequenceAndDraw ( fighter , 3 , kFightSequenceType1 ) ;
setSequenceAndDraw ( fighter - > opponent , ( action = = kFightAction1 ? 3 : 4 ) , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
if ( action = = kFightAction2 )
fighter - > countdown = 0 ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction5 :
if ( fighter - > sequenceIndex ! = 3 ) {
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
}
break ;
case kFightAction128 :
setSequenceAndDraw ( fighter , 1 , kFightSequenceType0 ) ;
fighter - > field_34 = 0 ;
break ;
case kFightAction131 :
setSequenceAndDraw ( fighter , 2 , ( fighter - > sequenceIndex ? kFightSequenceType2 : kFightSequenceType0 ) ) ;
break ;
}
}
void Fight : : updateSalko ( Fighter * fighter ) {
update ( fighter ) ;
// The original doesn't check for currentSequence2 != NULL (might not happen when everything is working properly, but crashes with our current implementation)
if ( fighter - > frame & & CHECK_SEQUENCE2 ( fighter , 2 ) ) {
if ( fighter - > opponent - > countdown < = 0 ) {
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
bailout ( kFightEndWin ) ;
return ;
}
if ( fighter - > sequenceIndex = = 2 )
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction2 ) ;
}
}
bool Fight : : canInteractSalko ( Fighter const * fighter , FightAction action ) {
if ( action = = kFightAction131 ) {
if ( fighter - > sequenceIndex = = 1 ) {
if ( fighter - > opponent - > countdown < = 0 )
_engine - > getCursor ( ) - > setStyle ( kCursorHand ) ;
return true ;
}
return false ;
}
return canInteract ( fighter ) ;
}
void Fight : : handleOpponentActionSalko ( Fighter * fighter , FightAction action ) {
if ( action = = kFightAction2 ) {
setSequenceAndDraw ( fighter , 5 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
} else {
handleAction ( fighter , action ) ;
}
}
void Fight : : updateOpponentSalko ( Fighter * fighter ) {
// This is an opponent struct
Opponent * opponent = ( Opponent * ) fighter ;
if ( ! opponent - > field_38 & & CALL_FUNCTION1 ( opponent , canInteract , kFightAction1 ) & & ! opponent - > sequenceIndex2 ) {
switch ( rnd ( 5 ) ) {
default :
break ;
case 0 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
break ;
case 1 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
break ;
case 2 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
case 3 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 1 , kFightSequenceType2 ) ;
break ;
case 4 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 1 , kFightSequenceType2 ) ;
break ;
}
// Update field_38
opponent - > field_38 = 4 * opponent - > countdown ;
}
if ( opponent - > frame & & CHECK_SEQUENCE2 ( opponent , 2 ) ) {
if ( opponent - > opponent - > countdown < = 0 ) {
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
bailout ( kFightEndLost ) ;
// Stop processing
return ;
}
if ( opponent - > sequenceIndex = = 1 | | opponent - > sequenceIndex = = 2 )
CALL_FUNCTION1 ( opponent - > opponent , handleAction , ( FightAction ) opponent - > sequenceIndex ) ;
}
updateOpponent ( opponent ) ;
}
//////////////////////////////////////////////////////////////////////////
// Vesna
//////////////////////////////////////////////////////////////////////////
void Fight : : loadVesnaPlayer ( ) {
REGISTER_PLAYER_FUNCTIONS ( Vesna )
_data - > player - > sequences . push_back ( loadSequence ( " 2005cr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2005cdr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2005cbr.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2005bk.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2005cdm1.seq " ) ) ;
_data - > player - > sequences . push_back ( loadSequence ( " 2005chl.seq " ) ) ;
}
void Fight : : loadVesnaOpponent ( ) {
REGISTER_OPPONENT_FUNCTIONS ( Vesna )
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005or.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005oam.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005oar.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005okml.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005okr.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005odm1.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005csbm.seq " ) ) ;
_data - > opponent - > sequences . push_back ( loadSequence ( " 2005oam4.seq " ) ) ;
getSound ( ) - > playSound ( kEntityTables0 , " MUS038 " , SoundManager : : kFlagDefault ) ;
_data - > opponent - > countdown = 4 ;
_data - > opponent - > field_38 = 30 ;
}
void Fight : : handleActionVesna ( Fighter * fighter , FightAction action ) {
switch ( action ) {
default :
handleAction ( fighter , action ) ;
return ;
case kFightAction1 :
if ( fighter - > sequenceIndex ! = 1 ) {
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction2 :
if ( fighter - > sequenceIndex ! = 2 ) {
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
} else {
fighter - > field_34 + + ;
}
break ;
case kFightAction5 :
if ( fighter - > sequenceIndex ! = 3 ) {
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
CALL_FUNCTION0 ( fighter , update ) ;
}
break ;
case kFightAction128 :
if ( fighter - > sequenceIndex = = 1 & & fighter - > opponent - > sequenceIndex = = 1 & & CHECK_SEQUENCE2 ( fighter , 4 ) ) {
setSequenceAndDraw ( fighter , 5 , kFightSequenceType1 ) ;
} else {
setSequenceAndDraw ( fighter , ( fighter - > opponent - > sequenceIndex = = 5 ) ? 3 : 1 , kFightSequenceType0 ) ;
}
break ;
case kFightAction132 :
setSequenceAndDraw ( fighter , 2 , kFightSequenceType0 ) ;
break ;
}
if ( fighter - > field_34 > 10 ) {
setSequenceAndDraw ( fighter - > opponent , 5 , kFightSequenceType2 ) ;
fighter - > opponent - > countdown = 1 ;
fighter - > field_34 = 0 ;
}
}
void Fight : : updateVesna ( Fighter * fighter ) {
if ( fighter - > frame & & CHECK_SEQUENCE2 ( fighter , 2 ) ) {
if ( fighter - > sequenceIndex = = 3 )
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction3 ) ;
if ( fighter - > opponent - > countdown < = 0 ) {
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
bailout ( kFightEndWin ) ;
return ;
}
if ( fighter - > sequenceIndex = = 5 )
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction5 ) ;
}
update ( fighter ) ;
}
bool Fight : : canInteractVesna ( Fighter const * fighter , FightAction action ) {
if ( action ! = kFightAction128 )
return canInteract ( fighter ) ;
if ( fighter - > sequenceIndex ! = 1 ) {
if ( fighter - > opponent - > sequenceIndex = = 5 ) {
_engine - > getCursor ( ) - > setStyle ( kCursorDown ) ;
return true ;
}
return canInteract ( fighter ) ;
}
if ( fighter - > opponent - > sequenceIndex = = 1 & & CHECK_SEQUENCE2 ( fighter , 4 ) ) {
_engine - > getCursor ( ) - > setStyle ( kCursorPunchLeft ) ;
return true ;
}
return false ;
}
void Fight : : handleOpponentActionVesna ( Fighter * fighter , FightAction action ) {
switch ( action ) {
default :
handleAction ( fighter , action ) ;
break ;
case kFightAction3 :
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
break ;
case kFightAction5 :
setSequenceAndDraw ( fighter , 7 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( fighter - > opponent , handleAction , kFightAction103 ) ;
if ( fighter - > countdown < = 1 )
fighter - > countdown = 1 ;
break ;
case kFightAction131 :
break ;
}
}
void Fight : : updateOpponentVesna ( Fighter * fighter ) {
// This is an opponent struct
Opponent * opponent = ( Opponent * ) fighter ;
if ( ! opponent - > field_38 & & CALL_FUNCTION1 ( opponent , canInteract , kFightAction1 ) & & ! opponent - > sequenceIndex2 ) {
if ( opponent - > opponent - > field_34 = = 1 ) {
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
} else {
switch ( rnd ( 6 ) ) {
default :
break ;
case 0 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
break ;
case 1 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 1 , kFightSequenceType2 ) ;
break ;
case 2 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
break ;
case 3 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
case 4 :
setSequenceAndDraw ( opponent , 1 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 2 , kFightSequenceType2 ) ;
break ;
case 5 :
setSequenceAndDraw ( opponent , 2 , kFightSequenceType0 ) ;
setSequenceAndDraw ( opponent , 1 , kFightSequenceType2 ) ;
break ;
}
}
// Update field_38
opponent - > field_38 = 4 * opponent - > countdown ;
}
if ( opponent - > frame & & CHECK_SEQUENCE2 ( opponent , 2 ) ) {
if ( opponent - > sequenceIndex = = 1 | | opponent - > sequenceIndex = = 2 | | opponent - > sequenceIndex = = 5 )
CALL_FUNCTION1 ( opponent - > opponent , handleAction , ( FightAction ) opponent - > sequenceIndex ) ;
if ( opponent - > opponent - > countdown < = 0 ) {
switch ( opponent - > sequenceIndex ) {
default :
break ;
case 1 :
setSequenceAndDraw ( opponent , 3 , kFightSequenceType1 ) ;
break ;
case 2 :
setSequenceAndDraw ( opponent , 4 , kFightSequenceType1 ) ;
break ;
case 5 :
setSequenceAndDraw ( opponent , 6 , kFightSequenceType1 ) ;
break ;
}
setSequenceAndDraw ( opponent - > opponent , 4 , kFightSequenceType1 ) ;
CALL_FUNCTION1 ( opponent , handleAction , kFightActionLost ) ;
CALL_FUNCTION0 ( opponent - > opponent , update ) ;
CALL_FUNCTION0 ( opponent , update ) ;
getSound ( ) - > removeFromQueue ( kEntityTables0 ) ;
// Stop processing
return ;
}
}
updateOpponent ( opponent ) ;
}
} // End of namespace LastExpress