Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTemplate::AIScriptTemplate(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptTemplate::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptTemplate::Update() {
return false;
}
void AIScriptTemplate::TimerExpired(int timer) {
//return false;
}
void AIScriptTemplate::CompletedMovementTrack() {
//return false;
}
void AIScriptTemplate::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTemplate::ClickedByPlayer() {
//return false;
}
void AIScriptTemplate::EnteredScene(int sceneId) {
// return false;
}
void AIScriptTemplate::OtherAgentEnteredThisScene(int otherActorId) {
// return false;
}
void AIScriptTemplate::OtherAgentExitedThisScene(int otherActorId) {
// return false;
}
void AIScriptTemplate::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTemplate::ShotAtAndMissed() {
// return false;
}
bool AIScriptTemplate::ShotAtAndHit() {
return false;
}
void AIScriptTemplate::Retired(int byActorId) {
// return false;
}
int AIScriptTemplate::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTemplate::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptTemplate::UpdateAnimation(int *animation, int *frame) {
*animation = 0;
*frame = _animationFrame;
return true;
}
bool AIScriptTemplate::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptTemplate::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTemplate::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTemplate::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTemplate::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptAnsweringMachine::AIScriptAnsweringMachine(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptAnsweringMachine::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptAnsweringMachine::Update() {
return false;
}
void AIScriptAnsweringMachine::TimerExpired(int timer) {
//return false;
}
void AIScriptAnsweringMachine::CompletedMovementTrack() {
//return false;
}
void AIScriptAnsweringMachine::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptAnsweringMachine::ClickedByPlayer() {
//return false;
}
void AIScriptAnsweringMachine::EnteredSet(int setId) {
// return false;
}
void AIScriptAnsweringMachine::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptAnsweringMachine::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptAnsweringMachine::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptAnsweringMachine::ShotAtAndMissed() {
// return false;
}
bool AIScriptAnsweringMachine::ShotAtAndHit() {
return false;
}
void AIScriptAnsweringMachine::Retired(int byActorId) {
// return false;
}
int AIScriptAnsweringMachine::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptAnsweringMachine::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptAnsweringMachine::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptAnsweringMachine::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptAnsweringMachine::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptAnsweringMachine::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptAnsweringMachine::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptAnsweringMachine::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,126 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptBaker::AIScriptBaker(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptBaker::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptBaker::Update() {
return false;
}
void AIScriptBaker::TimerExpired(int timer) {
//return false;
}
void AIScriptBaker::CompletedMovementTrack() {
//return false;
}
void AIScriptBaker::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptBaker::ClickedByPlayer() {
//return false;
}
void AIScriptBaker::EnteredSet(int setId) {
// return false;
}
void AIScriptBaker::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptBaker::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptBaker::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptBaker::ShotAtAndMissed() {
// return false;
}
bool AIScriptBaker::ShotAtAndHit() {
return false;
}
void AIScriptBaker::Retired(int byActorId) {
// return false;
}
int AIScriptBaker::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptBaker::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptBaker::UpdateAnimation(int *animation, int *frame) {
*animation = kModelAnimationBakerTpose;
*frame = 0;
return true;
}
bool AIScriptBaker::ChangeAnimationMode(int mode) {
debugC(6, kDebugAnimation, "AIScriptBaker::ChangeAnimationMode(%d) - Animation mode change is not supported", mode);
return true;
}
void AIScriptBaker::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptBaker::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptBaker::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptBaker::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,160 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
// Notes:
// kActorBlimpGuy's speech appears
// in specific scenes:
// - AR01, AR02
// - BB01
// - CT01, CT02, CT03, CT04, CT06, CT07, CT08, CT12
// - DR01, DR04
// - MA05
// - RC03
// and one cutscene:
// - TB_FLY
// In the in-game scenes (not cutscenes) this speech is played as ambient sound
// using Ambient_Sounds_Add_Speech_Sound() and is thus not subtitled as of yet.
// TODO: maybe we could support dual subtitles being displayed on-screen for cases when Ambient Speech Sound
// would overlap over character speech.
// The Blimp Guy's speech in the TB_FLY VQA cutscene is subtitled.
//
// The FRA and ESP versions do not use the Blimp's horn sound at all during any of the announcements
//
// From the available quotes for kActorBlimpGuy, only quotes with id 0, 20, 40, 50 are used.
// Quote 10 is unused:
// "A new life awaits you in the Off-World colonies."
// "The chance to begin again in a golden land of opportunity and adventure."
// - In ENG and DEU versions it is identical with the second half of quote id 0 and thus redundant
// - In FRA, ESP and ITA versions it is the missing second half of quote id 0 and is thus "required"
// TODO: Figure out a way to restore this quote as a continuation of the previous quote
// given that this is ambient sound!
//
// Quote 30 is unused:
// Roughly translates to: "What are you waiting for? Emigrate to the colonies!"
// - In ENG version this is a *boop* sound
// - In DEU version this is the start of a new announcement (the Blimp horn plays)
// - In ITA version this should be a continuation of an announcement (the Blimp horn does not play)
// - In FRA and ESP version this can be either a new announcement or a continuation of the previous announcement
// (the Blimp horn does not play ever in FRA and ESP versions)
// TODO: Figure out a way to restore this quote as a continuation of the previous quote
// given that this is ambient sound!
//
AIScriptBlimpGuy::AIScriptBlimpGuy(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptBlimpGuy::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptBlimpGuy::Update() {
return false;
}
void AIScriptBlimpGuy::TimerExpired(int timer) {
//return false;
}
void AIScriptBlimpGuy::CompletedMovementTrack() {
//return false;
}
void AIScriptBlimpGuy::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptBlimpGuy::ClickedByPlayer() {
//return false;
}
void AIScriptBlimpGuy::EnteredSet(int setId) {
// return false;
}
void AIScriptBlimpGuy::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptBlimpGuy::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptBlimpGuy::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptBlimpGuy::ShotAtAndMissed() {
// return false;
}
bool AIScriptBlimpGuy::ShotAtAndHit() {
return false;
}
void AIScriptBlimpGuy::Retired(int byActorId) {
// return false;
}
int AIScriptBlimpGuy::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptBlimpGuy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptBlimpGuy::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptBlimpGuy::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptBlimpGuy::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptBlimpGuy::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptBlimpGuy::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptBlimpGuy::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,320 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptBryant::AIScriptBryant(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptBryant::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
World_Waypoint_Set(324, kSetBB05, 267.0f, -60.3f, 203.0f);
World_Waypoint_Set(325, kSetBB05, 84.0f, -60.3f, 337.0f);
World_Waypoint_Set(326, kSetBB06_BB07, -36.0f, 0.0f, 185.0f);
World_Waypoint_Set(327, kSetBB06_BB07, -166.0f, 0.0f, -103.0f);
World_Waypoint_Set(328, kSetBB07, -556.0f, 252.59f, -1018.11f);
World_Waypoint_Set(329, kSetBB07, -655.0f, 252.6f, -1012.0f);
World_Waypoint_Set(330, kSetBB07, -657.0f, 253.0f, -1127.0f);
World_Waypoint_Set(331, kSetBB12, 163.8f, 0.0f, 67.0f);
World_Waypoint_Set(332, kSetBB06_BB07, -39.0f, 0.0f, 11.5f);
World_Waypoint_Set(333, kSetBB12, -34.0f, 0.0f, 33.0f);
World_Waypoint_Set(334, kSetBB05, 3.0f, -60.30f, -144.0f);
World_Waypoint_Set(335, kSetBB12, -50.0f, 0.0f, 212.0f);
Actor_Put_In_Set(kActorBryant, kSetBB05);
Actor_Set_Goal_Number(kActorBryant, 100);
}
bool AIScriptBryant::Update() {
if (Global_Variable_Query(kVariableChapter) == 2
&& Actor_Query_Goal_Number(kActorBryant) <= 101
&& Player_Query_Current_Scene() == kSceneBB05
) {
Actor_Set_Goal_Number(kActorBryant, 101);
return true;
}
if ( Global_Variable_Query(kVariableChapter) == 3
&& Player_Query_Current_Scene() == kSceneBB05
&& !Game_Flag_Query(kFlagNotUsed686)
) {
Game_Flag_Set(kFlagNotUsed686);
return true;
}
return false;
}
void AIScriptBryant::TimerExpired(int timer) {
//return false;
}
void AIScriptBryant::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorBryant) == 101) {
Actor_Set_Goal_Number(kActorBryant, 102);
// return true;
} else if (Actor_Query_Goal_Number(kActorBryant) == 102) {
Actor_Set_Goal_Number(kActorBryant, 101);
// return true;
}
// return false;
}
void AIScriptBryant::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptBryant::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorBryant, true);
Actor_Voice_Over(30, kActorVoiceOver);
Actor_Voice_Over(40, kActorVoiceOver);
}
void AIScriptBryant::EnteredSet(int setId) {
// return false;
}
void AIScriptBryant::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptBryant::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptBryant::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptBryant::ShotAtAndMissed() {
// return false;
}
bool AIScriptBryant::ShotAtAndHit() {
AI_Movement_Track_Flush(kActorBryant);
Sound_Play(kSfxFEMHURT1, 100, 0, 0, 50); // a bug?
return false;
}
void AIScriptBryant::Retired(int byActorId) {
// return false;
}
int AIScriptBryant::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptBryant::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 101:
AI_Movement_Track_Flush(kActorBryant);
switch (Random_Query(0, 9)) {
case 0:
AI_Movement_Track_Append(kActorBryant, 134, 0);
AI_Movement_Track_Append(kActorBryant, 135, 0);
AI_Movement_Track_Append(kActorBryant, 136, 0);
AI_Movement_Track_Append(kActorBryant, 137, 0);
AI_Movement_Track_Append(kActorBryant, 138, 0);
AI_Movement_Track_Append(kActorBryant, 139, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 1:
AI_Movement_Track_Append(kActorBryant, 139, 0);
AI_Movement_Track_Append(kActorBryant, 138, 0);
AI_Movement_Track_Append(kActorBryant, 137, 0);
AI_Movement_Track_Append(kActorBryant, 136, 0);
AI_Movement_Track_Append(kActorBryant, 135, 0);
AI_Movement_Track_Append(kActorBryant, 134, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 2:
AI_Movement_Track_Append(kActorBryant, 196, 0);
AI_Movement_Track_Append(kActorBryant, 197, 0);
AI_Movement_Track_Append(kActorBryant, 198, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 3:
AI_Movement_Track_Append(kActorBryant, 198, 0);
AI_Movement_Track_Append(kActorBryant, 197, 0);
AI_Movement_Track_Append(kActorBryant, 196, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 4:
AI_Movement_Track_Append(kActorBryant, 326, 0);
AI_Movement_Track_Append(kActorBryant, 332, 0);
AI_Movement_Track_Append(kActorBryant, 327, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 5:
AI_Movement_Track_Append(kActorBryant, 327, 0);
AI_Movement_Track_Append(kActorBryant, 332, 0);
AI_Movement_Track_Append(kActorBryant, 326, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 6:
AI_Movement_Track_Append(kActorBryant, 329, 0);
AI_Movement_Track_Append(kActorBryant, 328, 0);
AI_Movement_Track_Append(kActorBryant, 330, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 7:
AI_Movement_Track_Append(kActorBryant, 330, 0);
AI_Movement_Track_Append(kActorBryant, 328, 0);
AI_Movement_Track_Append(kActorBryant, 329, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 8:
AI_Movement_Track_Append(kActorBryant, 331, 0);
AI_Movement_Track_Append(kActorBryant, 333, 0);
AI_Movement_Track_Append(kActorBryant, 335, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
case 9:
AI_Movement_Track_Append(kActorBryant, 335, 0);
AI_Movement_Track_Append(kActorBryant, 333, 0);
AI_Movement_Track_Append(kActorBryant, 331, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
default:
break;
}
// fallthrough
case 102:
AI_Movement_Track_Append(kActorBryant, 39, 0);
AI_Movement_Track_Repeat(kActorBryant);
break;
default:
break;
}
return false;
}
bool AIScriptBryant::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationBearToyOscillatingIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBearToyOscillatingIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationBearToyWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBearToyWalking)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationBearToyShotDead;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBearToyShotDead) - 1) {
_animationState = 3;
}
break;
case 3:
*animation = kModelAnimationBearToyShotDead;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationBearToyShotDead) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptBryant::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptBryant::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_animationFrame = 0;
break;
case kAnimationModeWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 2;
_animationFrame = 0;
Actor_Set_Goal_Number(kActorBryant, 0);
break;
default:
debugC(6, kDebugAnimation, "AIScriptBryant::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptBryant::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptBryant::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptBryant::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptBryant::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,596 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptBulletBob::AIScriptBulletBob(BladeRunnerEngine *vm) : AIScriptBase(vm) {
// _varChooseIdleAnimation can have valid values: 0, 1
_varChooseIdleAnimation = 0;
_var2 = 6;
_var3 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
}
void AIScriptBulletBob::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_varChooseIdleAnimation = 0;
_var2 = 6;
_var3 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobDefault);
Actor_Set_Targetable(kActorBulletBob, true);
}
bool AIScriptBulletBob::Update() {
if (Game_Flag_Query(kFlagRC04McCoyShotBob)
&& Actor_Query_Goal_Number(kActorBulletBob) != kGoalBulletBobDead
) {
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobDead);
}
if ( Player_Query_Combat_Mode()
&& Player_Query_Current_Scene() == kSceneRC04
&& !Game_Flag_Query(kFlagRC04McCoyCombatMode)
&& Global_Variable_Query(kVariableChapter) < 4
) {
AI_Countdown_Timer_Reset(kActorBulletBob, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorBulletBob, kActorTimerAIScriptCustomTask2, 10);
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobWarningMcCoy);
Actor_Modify_Friendliness_To_Other(kActorBulletBob, kActorMcCoy, -15);
Game_Flag_Set(kFlagRC04McCoyCombatMode);
} else if ( Actor_Query_Goal_Number(kActorBulletBob) == kGoalBulletBobWarningMcCoy
&& !Player_Query_Combat_Mode()
) {
AI_Countdown_Timer_Reset(kActorBulletBob, kActorTimerAIScriptCustomTask2);
Game_Flag_Reset(kFlagRC04McCoyCombatMode);
Game_Flag_Set(kFlagRC04McCoyWarned);
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobDefault);
}
if ( Actor_Query_Goal_Number(kActorBulletBob) == kGoalBulletBobShootMcCoy
&& !Game_Flag_Query(kFlagRC04BobShootMcCoy)
&& _animationState == 0
) {
Actor_Face_Heading(kActorBulletBob, 208, false);
_animationFrame = 0;
_animationState = 2;
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobWillShotMcCoy);
Game_Flag_Set(kFlagRC04BobShootMcCoy);
return true;
}
if (Game_Flag_Query(kFlagRC04McCoyWarned)
&& Player_Query_Combat_Mode()
&& Actor_Query_Goal_Number(kActorBulletBob) != kGoalBulletBobDead
) {
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobShootMcCoy);
return true;
}
return false;
}
void AIScriptBulletBob::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2
&& Actor_Query_Goal_Number(kActorBulletBob) == kGoalBulletBobWarningMcCoy
) {
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobShootMcCoy);
AI_Countdown_Timer_Reset(kActorBulletBob, kActorTimerAIScriptCustomTask2);
return; //true;
}
return; //false;
}
void AIScriptBulletBob::CompletedMovementTrack() {
//return false;
}
void AIScriptBulletBob::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptBulletBob::ClickedByPlayer() {
//return false;
}
void AIScriptBulletBob::EnteredSet(int setId) {
// return false;
}
void AIScriptBulletBob::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptBulletBob::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptBulletBob::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptBulletBob::ShotAtAndMissed() {
// return false;
}
bool AIScriptBulletBob::ShotAtAndHit() {
Global_Variable_Increment(kVariableBobShot, 1);
if (Global_Variable_Query(kVariableBobShot) > 0) {
Actor_Set_Targetable(kActorBulletBob, false);
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobGone);
_animationFrame = 0;
_animationState = 3;
Ambient_Sounds_Play_Speech_Sound(kActorGordo, 9000, 100, 0, 0, 0); // not a typo, it's really from Gordo
Actor_Face_Heading(kActorBulletBob, 281, false);
}
return false;
}
void AIScriptBulletBob::Retired(int byActorId) {
// return false;
}
int AIScriptBulletBob::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptBulletBob::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == kGoalBulletBobDefault
&& Game_Flag_Query(kFlagRC04McCoyWarned)
&& Player_Query_Current_Scene() == kSceneRC04
) {
Actor_Says(kActorBulletBob, 140, 16);
return true;
}
if ( newGoalNumber == kGoalBulletBobWarningMcCoy
&& !Game_Flag_Query(kFlagRC04McCoyWarned)
&& Player_Query_Current_Scene() == kSceneRC04
) {
Actor_Says(kActorBulletBob, 120, 37);
Actor_Says(kActorMcCoy, 4915, 13);
return true;
}
if ( newGoalNumber == kGoalBulletBobDead
&& !Actor_Clue_Query(kActorMcCoy, kClueVKBobGorskyReplicant)
) {
Delay(2000);
Actor_Voice_Over(2100, kActorVoiceOver);
Actor_Voice_Over(2110, kActorVoiceOver);
Actor_Voice_Over(2120, kActorVoiceOver);
Actor_Voice_Over(2130, kActorVoiceOver);
return true;
}
if (newGoalNumber == kGoalBulletBobShotMcCoy) {
Scene_Exits_Disable();
Actor_Force_Stop_Walking(kActorMcCoy);
Ambient_Sounds_Play_Speech_Sound(kActorMcCoy, 9900, 100, 0, 0, 0);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
Actor_Retired_Here(kActorMcCoy, 6, 6, true, -1);
Scene_Exits_Enable();
return true;
}
return false;
}
bool AIScriptBulletBob::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 1) {
#if BLADERUNNER_ORIGINAL_BUGS
// TODO a bug? Why use kModelAnimationBulletBobSittingHeadMoveDownThink (516) here
// and leave kModelAnimationBulletBobSittingHeadMoveAround (515) unused?
// Also below kModelAnimationBulletBobSittingHeadMoveAround (515) is used
// in Slice_Animation_Query_Number_Of_Frames(),
// even though the count of frames is identical in both 515 and 516 framesets
*animation = kModelAnimationBulletBobSittingHeadMoveDownThink;
#else
*animation = kModelAnimationBulletBobSittingHeadMoveAround;
#endif
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
if (++_animationFrame == 6) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(4, 8);
}
if (_animationFrame == 11) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(2, 6);
}
// frames in frameset kModelAnimationBulletBobSittingHeadMoveAround (515): 16
// frames in frameset kModelAnimationBulletBobSittingHeadMoveDownThink (kModelAnimationBulletBobSittingHeadMoveDownThink): 16
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingHeadMoveAround)) {
_animationFrame = 0;
_varChooseIdleAnimation = 0;
_var3 = 2 * Random_Query(0, 1) - 1;
_var2 = Random_Query(3, 7);
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 4);
}
}
} else if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationBulletBobSittingIdle;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
_animationFrame += _var3;
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingIdle) - 1;
} else if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingIdle)) {
_animationFrame = 0;
}
if (!--_var2) {
_var3 = 2 * Random_Query(0, 1) - 1;
_var2 = Random_Query(3, 7);
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 4);
}
if (_animationFrame == 0) {
_varChooseIdleAnimation = Random_Query(0, 1);
}
}
}
break;
case 1:
*animation = kModelAnimationBulletBobSittingCombatIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCombatIdle)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationBulletBobSittingCombatFiresGun;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCombatFiresGun)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationBulletBobSittingCombatIdle;
}
if (_animationFrame == 10) {
Sound_Play(kSfxSHOTCOK1, 75, 0, 0, 50);
}
if (_animationFrame == 5) {
Sound_Play(kSfxSHOTGUN1, 90, 0, 0, 50);
Actor_Set_Goal_Number(kActorBulletBob, kGoalBulletBobShotMcCoy);
}
break;
case 3:
*animation = kModelAnimationBulletBobSittingCombatShotDead;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCombatShotDead) - 1) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCombatShotDead) - 1;
_animationState = 16;
Game_Flag_Set(kFlagRC04McCoyShotBob);
}
break;
case 4:
break;
case 5:
*animation = kModelAnimationBulletBobSittingThumbsUp;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingThumbsUp)) {
*animation = kModelAnimationBulletBobSittingIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 6:
*animation = kModelAnimationBulletBobSittingCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCalmTalk)) {
_animationFrame = 0;
}
break;
case 7:
*animation = kModelAnimationBulletBobSittingDismissiveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingDismissiveTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case 8:
*animation = kModelAnimationBulletBobSittingSuggestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingSuggestTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case 9:
*animation = kModelAnimationBulletBobSittingQuickSuggestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingQuickSuggestTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case 10:
*animation = kModelAnimationBulletBobSittingExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingExplainTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case 11:
*animation = kModelAnimationBulletBobSittingGossipTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingGossipTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case 12:
*animation = kModelAnimationBulletBobSittingHeadNodLeftTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingHeadNodLeftTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case 13:
*animation = kModelAnimationBulletBobSittingPersistentTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingPersistentTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case 14:
*animation = kModelAnimationBulletBobSittingCombatRetrievesGun;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCombatRetrievesGun)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationBulletBobSittingCombatIdle;
}
break;
case 15:
if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationBulletBobSittingHeadMoveDownThink;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingHeadMoveDownThink)) {
_animationFrame += 2;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingHeadMoveDownThink)) {
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
}
} else {
_animationFrame -= 2;
if (_animationFrame <= 0) {
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
}
}
} else if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationBulletBobSittingIdle;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingIdle)) {
_animationFrame += 2;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingIdle)) {
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
}
} else {
_animationFrame -= 2;
if (_animationFrame <= 0) {
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
}
}
}
break;
case 16:
*animation = kModelAnimationBulletBobSittingCombatShotDead;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCombatShotDead) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptBulletBob::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptBulletBob::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState > 4 || _animationState) {
// TODO "|| _animationState" part of the clause does not make sense (makes the first part redundant). A bug?
_animationState = 0;
_animationFrame = 0;
}
break;
case kAnimationModeTalk:
// fall through
case 9:
// fall through
case 30:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 6;
_animationNext = kModelAnimationBulletBobSittingCalmTalk;
}
break;
case kAnimationModeCombatIdle:
if (_animationState <= 4 && _animationState == 0) {
_animationState = 14;
_animationFrame = 0;
}
break;
case kAnimationModeCombatAttack:
_animationState = 2;
_animationFrame = 0;
break;
case 10:
// fall through
case 31:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 7;
_animationNext = kModelAnimationBulletBobSittingDismissiveTalk;
}
break;
case 11:
// fall through
case 33:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 9;
_animationNext = kModelAnimationBulletBobSittingQuickSuggestTalk;
}
break;
case kAnimationModeHit:
// fall through
case kAnimationModeCombatHit:
_animationState = 3;
_animationFrame = 0;
break;
case 23:
_animationState = 5;
_animationFrame = 0;
break;
case 32:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 8;
_animationNext = kModelAnimationBulletBobSittingSuggestTalk;
}
break;
case 34:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 10;
_animationNext = kModelAnimationBulletBobSittingExplainTalk;
}
break;
case 35:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 11;
_animationNext = kModelAnimationBulletBobSittingGossipTalk;
}
break;
case 36:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 12;
_animationNext = kModelAnimationBulletBobSittingHeadNodLeftTalk;
}
break;
case 37:
if (_animationState < 6 || _animationState > 13) {
_animationState = 15;
_animationStateNext = 13;
_animationNext = kModelAnimationBulletBobSittingPersistentTalk;
}
break;
case kAnimationModeDie:
_animationState = 4;
_animationFrame = 0;
break;
case 88:
_animationState = 16;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobSittingCombatShotDead) - 1;
break;
default:
_animationState = 0;
_animationFrame = 0;
debugC(6, kDebugAnimation, "AIScriptBulletBob::ChangeAnimationMode(%d) - Target mode is treated as default, state and frame are set to 0", mode);
break;
}
return true;
}
void AIScriptBulletBob::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptBulletBob::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptBulletBob::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptBulletBob::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,505 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptChew::AIScriptChew(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
_varNumOfTimesToHoldCurrentFrame = 0;
// _varChooseIdleAnimation can have valid values: 0, 1, 2
_varChooseIdleAnimation = 0;
_var3 = 1;
}
void AIScriptChew::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_varNumOfTimesToHoldCurrentFrame = 0;
_varChooseIdleAnimation = 0;
_var3 = 1;
}
bool AIScriptChew::Update() {
return false;
}
void AIScriptChew::TimerExpired(int timer) {
//return false;
}
void AIScriptChew::CompletedMovementTrack() {
//return false;
}
void AIScriptChew::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptChew::ClickedByPlayer() {
//return false;
}
void AIScriptChew::EnteredSet(int setId) {
// return false;
}
void AIScriptChew::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptChew::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptChew::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptChew::ShotAtAndMissed() {
// return false;
}
bool AIScriptChew::ShotAtAndHit() {
return false;
}
void AIScriptChew::Retired(int byActorId) {
// return false;
}
int AIScriptChew::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptChew::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptChew::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationChewIdle;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewIdle)) {
_animationFrame = 0;
_var3 = 1;
_varChooseIdleAnimation = Random_Query(0, 2);
} else if (!Random_Query(0, 1)) {
_varNumOfTimesToHoldCurrentFrame = 1;
if (!Random_Query(0, 3)) {
_var3 = -_var3;
}
}
}
} else if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationChewFiddlingWithInstruments;
_animationFrame += _var3;
if (_animationFrame <= 6) {
_var3 = 1;
}
if (_animationFrame == 13) {
if (!Random_Query(0, 1)) {
_var3 = -1;
}
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewFiddlingWithInstruments)) {
_animationFrame = 0;
_varChooseIdleAnimation = Random_Query(0, 2);
_var3 = 1;
}
} else if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationChewAdjustingInstrument;
_animationFrame += _var3;
if (_animationFrame <= 8) {
_var3 = 1;
}
if (_animationFrame == 16) {
if (!Random_Query(0, 1)) {
_var3 = -1;
}
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewAdjustingInstrument)) {
_animationFrame = 0;
_varChooseIdleAnimation = Random_Query(0, 2);
_var3 = 1;
}
}
break;
case 1:
if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationChewIdle;
}
if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationChewFiddlingWithInstruments;
}
if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationChewAdjustingInstrument;
}
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame += 2;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
} else {
_animationFrame -= 2;
if (_animationFrame <= 0) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
}
break;
case 2:
*animation = kModelAnimationChewProtestTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationChewIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewProtestTalk)) {
_animationFrame = 0;
}
}
break;
case 3:
*animation = kModelAnimationChewAngryTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewAngryTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
case 4:
*animation = kModelAnimationChewExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewExplainTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
case 5:
*animation = kModelAnimationChewGoAwayTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewGoAwayTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
case 6:
*animation = kModelAnimationChewDismissiveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewDismissiveTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
case 7:
*animation = kModelAnimationChewPointingSomewhereTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewPointingSomewhereTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
case 8:
*animation = kModelAnimationChewDescribePulledTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewDescribePulledTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
case 9:
*animation = kModelAnimationChewDescribePushedTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewDescribePushedTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
case 10:
*animation = kModelAnimationChewGotHit;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewGotHit)) {
*animation = kModelAnimationChewIdle;
_animationFrame = 0;
_animationState = 0;
_varChooseIdleAnimation = 0;
}
break;
case 11:
*animation = kModelAnimationChewShotDead;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewShotDead) - 1) {
++_animationFrame;
}
break;
case 12:
*animation = kModelAnimationChewWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewWalking)) {
_animationFrame = 0;
}
break;
case 13:
*animation = kModelAnimationChewTakesAStepBackwards;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationChewTakesAStepBackwards)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationChewProtestTalk;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptChew::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptChew::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
switch (_animationState) {
case 0:
return true;
case 2:
// fall through
case 3:
// fall through
case 4:
// fall through
case 5:
// fall through
case 6:
// fall through
case 7:
// fall through
case 8:
// fall through
case 9:
_resumeIdleAfterFramesetCompletesFlag = true;
break;
default:
_animationState = 0;
_varChooseIdleAnimation = 0;
_animationFrame = 0;
break;
}
break;
case kAnimationModeWalk:
_animationFrame = 0;
_animationState = 12;
break;
case 3:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 2;
_animationNext = kModelAnimationChewProtestTalk;
_animationState = 1;
}
}
break;
case 12:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 3;
_animationNext = kModelAnimationChewAngryTalk;
_animationState = 1;
}
}
break;
case 13:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 4;
_animationNext = kModelAnimationChewExplainTalk;
_animationState = 1;
}
}
break;
case 14:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 5;
_animationNext = kModelAnimationChewGoAwayTalk;
_animationState = 1;
}
}
break;
case 15:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 6;
_animationNext = kModelAnimationChewDismissiveTalk;
_animationState = 1;
}
}
break;
case 16:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 7;
_animationNext = kModelAnimationChewPointingSomewhereTalk;
_animationState = 1;
}
}
break;
case 17:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 8;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 8;
_animationNext = kModelAnimationChewDescribePulledTalk;
_animationState = 1;
}
}
break;
case 18:
if (_animationState < 2 || _animationState > 9) {
if (_animationState > 0) {
_animationState = 9;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationStateNext = 9;
_animationNext = kModelAnimationChewDescribePushedTalk;
_animationState = 1;
}
}
break;
case 43:
if (_animationState > 0 || (_animationState == 0 && _varChooseIdleAnimation != 1 && _varChooseIdleAnimation != 2)) {
Actor_Change_Animation_Mode(kActorChew, kAnimationModeIdle);
_varChooseIdleAnimation = Random_Query(1, 2);
}
break;
case kAnimationModeDie:
_animationFrame = 0;
_animationState = 11;
break;
default:
debugC(6, kDebugAnimation, "AIScriptChew::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptChew::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptChew::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptChew::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptChew::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,524 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kCrazylegsStates {
kCrazylegsStateIdle = 0,
kCrazylegsStateHandsUp = 1,
kCrazylegsStateMobileCall = 2
// TODO fill in the rest of the animationStates
};
AIScriptCrazylegs::AIScriptCrazylegs(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptCrazylegs::Initialize() {
_animationFrame = 0;
_animationState = kCrazylegsStateIdle;
_animationStateNext = kCrazylegsStateIdle;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
World_Waypoint_Set(360, kSetHF05, -103.0f, 40.63f, -53.0f);
Actor_Put_In_Set(kActorCrazylegs, kSetHF05);
Actor_Set_At_XYZ(kActorCrazylegs, -33.0f, 40.63f, 16.0f, 845);
}
bool AIScriptCrazylegs::Update() {
if (Actor_Query_Goal_Number(kActorCrazylegs) == 10)
Actor_Set_Goal_Number(kActorCrazylegs, 11);
return false;
}
void AIScriptCrazylegs::TimerExpired(int timer) {
//return false;
}
void AIScriptCrazylegs::CompletedMovementTrack() {
//return false;
}
void AIScriptCrazylegs::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptCrazylegs::ClickedByPlayer() {
//return false;
}
void AIScriptCrazylegs::EnteredSet(int setId) {
// return false;
}
void AIScriptCrazylegs::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptCrazylegs::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptCrazylegs::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (Actor_Query_Goal_Number(kActorCrazylegs) != kGoalCrazyLegsLeavesShowroom && otherActorId == kActorMcCoy) {
if (combatMode && Global_Variable_Query(kVariableChapter) < 5
&& (!_vm->_cutContent || Actor_Query_In_Set(kActorCrazylegs, kSetHF05))) {
Actor_Face_Actor(kActorCrazylegs, kActorMcCoy, true);
Actor_Face_Actor(kActorMcCoy, kActorCrazylegs, true);
Actor_Says(kActorCrazylegs, 430, 3);
Actor_Says_With_Pause(kActorCrazylegs, 440, 0.0f, 3);
Actor_Says(kActorMcCoy, 1870, -1);
Actor_Says(kActorCrazylegs, 450, 3);
Actor_Set_Goal_Number(kActorCrazylegs, kGoalCrazyLegsMcCoyDrewHisGun);
} else if (Actor_Query_Goal_Number(kActorCrazylegs) == kGoalCrazyLegsMcCoyDrewHisGun) {
Actor_Face_Actor(kActorCrazylegs, kActorMcCoy, true);
Actor_Says(kActorCrazylegs, 460, 3);
Actor_Says(kActorCrazylegs, 470, 3);
Actor_Set_Goal_Number(kActorCrazylegs, kGoalCrazyLegsLeavesShowroom);
}
}
}
void AIScriptCrazylegs::ShotAtAndMissed() {
if (Actor_Query_Goal_Number(kActorCrazylegs) == kGoalCrazyLegsLeavesShowroom)
return;
Actor_Set_Goal_Number(kActorCrazylegs, kGoalCrazyLegsLeavesShowroom);
}
bool AIScriptCrazylegs::ShotAtAndHit() {
Actor_Set_Goal_Number(kActorCrazylegs, kGoalCrazyLegsShotAndHit);
Actor_Says(kActorMcCoy, 1875, 4); // I wouldn't drag that bucket of bolts if you paid me.
return false;
}
void AIScriptCrazylegs::Retired(int byActorId) {
// return false;
}
int AIScriptCrazylegs::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptCrazylegs::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == kGoalCrazyLegsDefault) {
return true;
}
if (newGoalNumber == kGoalCrazyLegsShotAndHit) {
AI_Movement_Track_Flush(kActorCrazylegs);
Actor_Set_Targetable(kActorCrazylegs, false);
return true;
}
if (newGoalNumber == kGoalCrazyLegsLeavesShowroom) {
AI_Movement_Track_Flush(kActorCrazylegs);
AI_Movement_Track_Append(kActorCrazylegs, 360, 0);
AI_Movement_Track_Append(kActorCrazylegs, 40, 0);
AI_Movement_Track_Repeat(kActorCrazylegs);
return true;
}
return false;
}
bool AIScriptCrazylegs::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kCrazylegsStateIdle:
*animation = kModelAnimationCrazylegsIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsIdle))
_animationFrame = 0;
break;
case kCrazylegsStateHandsUp:
*animation = kModelAnimationCrazylegsHandsUpIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsHandsUpIdle))
_animationFrame = 0;
break;
case kCrazylegsStateMobileCall:
*animation = kModelAnimationCrazylegsMobileIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsMobileIdle))
_animationFrame = 0;
break;
case 3:
*animation = kModelAnimationCrazylegsGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsGestureGive)) {
*animation = kModelAnimationCrazylegsIdle;
_animationFrame = 0;
_animationState = kCrazylegsStateIdle;
}
break;
case 4:
*animation = kModelAnimationCrazylegsRollSlow;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsRollSlow))
_animationFrame = 0;
break;
case 5:
*animation = kModelAnimationCrazylegsRollFast;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsRollFast))
_animationFrame = 0;
break;
case 6:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationCrazylegsIdle;
_animationState = kCrazylegsStateIdle;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
*animation = kModelAnimationCrazylegsCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsCalmTalk))
_animationFrame = 0;
}
break;
case 7:
*animation = kModelAnimationCrazylegsSmallHandMoveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsSmallHandMoveTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 8:
*animation = kModelAnimationCrazylegsPointingAtSelfTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsPointingAtSelfTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 9:
*animation = kModelAnimationCrazylegsDisagreeTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsDisagreeTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 10:
*animation = kModelAnimationCrazylegsFastTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsFastTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 11:
*animation = kModelAnimationCrazylegsProtestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsProtestTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 12:
*animation = kModelAnimationCrazylegsMobileCalmTalk;
++_animationFrame;
// This is probably an untriggered animation
// TODO This animation has a faulty last frame which "breaks" its looping consistency
// TODO It should not lead to kModelAnimationCrazylegsCalmTalk but to one of Crazylegs mobile animations
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsMobileCalmTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 13:
*animation = kModelAnimationCrazylegsMobileIntenseTalk;
++_animationFrame;
// This is probably an untriggered animation
// TODO It should not lead to kModelAnimationCrazylegsCalmTalk but to one of Crazylegs mobile animations
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsMobileIntenseTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 14:
*animation = kModelAnimationCrazylegsHandsUpTalk;
++_animationFrame;
// This is probably an untriggered animation
// TODO It should not lead to kModelAnimationCrazylegsCalmTalk but to one of Crazylegs hands-up animations
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsHandsUpTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelAnimationCrazylegsCalmTalk;
}
break;
case 15:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
Actor_Change_Animation_Mode(kActorCrazylegs, 43);
_animationState = kCrazylegsStateMobileCall;
_resumeIdleAfterFramesetCompletesFlag = false;
*animation = kModelAnimationCrazylegsMobileIdle;
} else {
*animation = kModelAnimationCrazylegsMobileIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsMobileIdle))
_animationFrame = 0;
}
break;
case 16:
*animation = kModelAnimationCrazylegsHandsUpRaisesHands;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsHandsUpRaisesHands)) {
_animationFrame = 0;
_animationState = kCrazylegsStateHandsUp;
*animation = kModelAnimationCrazylegsHandsUpIdle;
}
break;
case 17:
*animation = kModelAnimationCrazylegsHandsUpLowersHands;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsHandsUpLowersHands)) {
*animation = kModelAnimationCrazylegsIdle;
_animationFrame = 0;
_animationState = kCrazylegsStateIdle;
}
break;
case 18:
// This animation plays in reverse
// TODO Code seems wrong (especially the if clause condition).
// Probably left like this because the animation is untriggered
*animation = kModelAnimationCrazylegsHangsUpMobile;
--_animationFrame;
if (_animationFrame <= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsHangsUpMobile)) { // matches original
_animationFrame = 0;
_animationState = kCrazylegsStateMobileCall;
*animation = kModelAnimationCrazylegsIdle;
}
break;
case 19:
*animation = kModelAnimationCrazylegsHangsUpMobile;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsHangsUpMobile)) {
*animation = kModelAnimationCrazylegsIdle;
_animationFrame = 0;
_animationState = kCrazylegsStateIdle;
if (Actor_Query_Goal_Number(kActorCrazylegs) == 10) {
Actor_Set_Goal_Number(kActorCrazylegs, 11);
}
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptCrazylegs::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptCrazylegs::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
switch (_animationState) {
case kCrazylegsStateIdle:
// fall through
case 3:
return true;
case kCrazylegsStateHandsUp:
_animationState = 17;
_animationFrame = 0;
break;
case kCrazylegsStateMobileCall:
_animationState = 19;
_animationFrame = 0;
break;
case 4:
// fall through
case 5:
_animationState = kCrazylegsStateIdle;
_animationFrame = 0;
break;
case 6:
// fall through
case 7:
// fall through
case 8:
// fall through
case 9:
// fall through
case 10:
// fall through
case 11:
// fall through
case 12:
// fall through
case 13:
// fall through
case 14:
// fall through
case 15:
_resumeIdleAfterFramesetCompletesFlag = true;
break;
default:
break;
}
break;
case kAnimationModeWalk:
_animationState = 4;
_animationFrame = 0;
break;
case kAnimationModeTalk:
if (_animationState == kCrazylegsStateMobileCall) {
_animationState = 15;
} else {
_animationState = 6;
}
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 8;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 9;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 10;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 16:
_animationState = 11;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 17:
_animationState = 12;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 18:
_animationState = 13;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 19:
_animationState = 14;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 23:
_animationState = 3;
_animationFrame = 0;
break;
case 43:
// picks up mobile phone call
if (_animationState != kCrazylegsStateMobileCall) {
_animationState = 18;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationCrazylegsHangsUpMobile) - 1;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptCrazylegs::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptCrazylegs::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptCrazylegs::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptCrazylegs::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptCrazylegs::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,413 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptDeskClerk::AIScriptDeskClerk(BladeRunnerEngine *vm) : AIScriptBase(vm) {
// _varChooseIdleAnimation can have valid values: 0, 1
_varChooseIdleAnimation = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_varNumOfTimesToHoldCurrentFrame = 75;
}
void AIScriptDeskClerk::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_varChooseIdleAnimation = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_varNumOfTimesToHoldCurrentFrame = 75;
Actor_Set_Goal_Number(kActorDeskClerk, kGoalDeskClerkDefault);
}
bool AIScriptDeskClerk::Update() {
if (Actor_Query_Goal_Number(kActorDeskClerk) == kGoalDeskClerkKnockedOut
&& Player_Query_Current_Set() != kSetCT01_CT12
&& Player_Query_Current_Set() != kSetCT03_CT04
&& Player_Query_Current_Set() != kSetCT08_CT51_UG12
&& Player_Query_Current_Set() != kSetCT02
&& Player_Query_Current_Set() != kSetCT05
&& Player_Query_Current_Set() != kSetCT06
&& Player_Query_Current_Set() != kSetCT07
&& Player_Query_Current_Set() != kSetCT09
&& Player_Query_Current_Set() != kSetCT10
&& Player_Query_Current_Set() != kSetCT11
) {
Actor_Set_Goal_Number(kActorDeskClerk, kGoalDeskClerkRecovered);
}
if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorDeskClerk) < kGoalDeskClerkGone
) {
Actor_Set_Goal_Number(kActorDeskClerk, kGoalDeskClerkGone);
}
return false;
}
void AIScriptDeskClerk::TimerExpired(int timer) {
//return false;
}
void AIScriptDeskClerk::CompletedMovementTrack() {
//return false;
}
void AIScriptDeskClerk::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptDeskClerk::ClickedByPlayer() {
//return false;
}
void AIScriptDeskClerk::EnteredSet(int setId) {
// return false;
}
void AIScriptDeskClerk::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptDeskClerk::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptDeskClerk::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptDeskClerk::ShotAtAndMissed() {
// return false;
}
bool AIScriptDeskClerk::ShotAtAndHit() {
return false;
}
void AIScriptDeskClerk::Retired(int byActorId) {
// return false;
}
int AIScriptDeskClerk::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptDeskClerk::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalDeskClerkDefault:
// fall through
case kGoalDeskClerkRecovered:
Actor_Put_In_Set(kActorDeskClerk, kSetCT09);
Actor_Set_At_XYZ(kActorDeskClerk, 282.0f, 360.52f, 743.0f, 513);
#if BLADERUNNER_ORIGINAL_BUGS
#else
Actor_Change_Animation_Mode(kActorDeskClerk, kAnimationModeIdle);
_animationFrame = 0;
_animationState = 0;
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case kGoalDeskClerkKnockedOut:
// fall through
case kGoalDeskClerkGone:
Actor_Put_In_Set(kActorDeskClerk, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorDeskClerk, 40, 0);
break;
}
return false;
}
bool AIScriptDeskClerk::UpdateAnimation(int *animation, int *frame) {
#if BLADERUNNER_ORIGINAL_BUGS
#else
// Fixing a bug for when the Clerk gets stuck in animation id kModelAnimationDeskClerkIsHeldUpByLeonIdle (668), after Act 3:
// - when using HDFRAMES, the clerk will briefly be in the choking animation when McCoy re-enters
// - when using CDFRAMES, the game would crash with a message:
// "Unable to locate page 2214 for animation 668 frame 4!"
// This occurs when:
// The player walks out too fast from the scene where Leon is choking the clerk in Act 3.
// Hence, Leon's AI script's OtherAgentExitedThisSet() is triggered, Leon is gone,
// and DeskClerk goal is set to kGoalDeskClerkKnockedOut which puts him in kSetFreeSlotH without changing his animation id.
// Thus later on, when the player leaves Chinatown and returns, DeskClerk's (update()) will set his goal to kGoalDeskClerkRecovered
// In Act 4, the CDFRAMES#.DAT method loads a reduced number of animations for DeskClerk causing the crash when McCoy visits the Yukon lobby.
//
// The following fix will work with awry saved games too (even from the original game in theory),
// that have this buggy state stored.
// We also include the rest of the problematic states that are missing animations in Act 4
// (ie. all _animationState >= 6)
if (Global_Variable_Query(kVariableChapter) > 3
&& _animationState >= 6
) {
Actor_Change_Animation_Mode(kActorDeskClerk, kAnimationModeIdle);
*animation = kModelAnimationDeskClerkReadPaperIdle;
_animationFrame = 0;
_animationState = 0;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation > 0) {
*animation = kModelAnimationDeskClerkReadPaperChangePageIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkReadPaperChangePageIdle)) {
_animationFrame = 0;
_varChooseIdleAnimation = 0;
*animation = kModelAnimationDeskClerkReadPaperIdle;
_varNumOfTimesToHoldCurrentFrame = Random_Query(50, 100);
}
} else {
if (_varNumOfTimesToHoldCurrentFrame != 0) {
--_varNumOfTimesToHoldCurrentFrame;
}
*animation = kModelAnimationDeskClerkReadPaperIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkReadPaperIdle)) {
_animationFrame = 0;
if (_varNumOfTimesToHoldCurrentFrame == 0) {
*animation = kModelAnimationDeskClerkReadPaperChangePageIdle;
_varChooseIdleAnimation = 1;
}
}
}
break;
case 1:
*animation = kModelAnimationDeskClerkReadPaperCalmTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationDeskClerkReadPaperIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
}
break;
case 2:
*animation = kModelAnimationDeskClerkReadPaperMoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkReadPaperMoreCalmTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationDeskClerkReadPaperCalmTalk;
}
break;
case 3:
*animation = kModelAnimationDeskClerkReadPaperMoveLeftTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkReadPaperMoveLeftTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationDeskClerkReadPaperCalmTalk;
}
break;
case 4:
*animation = kModelAnimationDeskClerkReadPaperSlightClosePaperTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkReadPaperSlightClosePaperTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationDeskClerkReadPaperCalmTalk;
}
break;
case 5:
*animation = kModelAnimationDeskClerkReadPaperMoreClosePaperTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkReadPaperMoreClosePaperTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationDeskClerkReadPaperCalmTalk;
}
break;
case 6:
*animation = kModelAnimationDeskClerkIsHeldUpByLeonIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkIsHeldUpByLeonIdle)) {
_animationFrame = 0;
}
break;
case 7:
*animation = kModelAnimationDeskClerkFallingAfterLeonLetsGo;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
Actor_Change_Animation_Mode(kActorDeskClerk, 72);
*animation = kModelAnimationDeskClerkIsHeldUpByLeonIdle;
_animationState = 6;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
}
break;
case 8:
*animation = kModelAnimationDeskClerkHeadSmashedOnCounter;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationDeskClerkHeadSmashedOnCounter) - 2) {
Ambient_Sounds_Play_Sound(kSfxZUBLAND1, 40, 30, 30, 99);
Actor_Set_Goal_Number(kActorDeskClerk, kGoalDeskClerkKnockedOut);
Actor_Change_Animation_Mode(kActorDeskClerk, kAnimationModeIdle);
*animation = kModelAnimationDeskClerkReadPaperIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptDeskClerk::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptDeskClerk::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
switch (_animationState) {
case 0:
_animationState = 8;
_animationFrame = 0;
break;
case 1:
// fall through
case 2:
// fall through
case 3:
// fall through
case 4:
// fall through
case 5:
_resumeIdleAfterFramesetCompletesFlag = true;
break;
case 6:
Actor_Change_Animation_Mode(kActorDeskClerk, 72);
break;
default:
_animationState = 0;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = Random_Query(70, 140);
break;
}
break;
case kAnimationModeTalk:
_animationState = 1;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 26:
_animationState = 8;
_animationFrame = 0;
break;
case 58:
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 72:
if (_animationState != 6) {
_animationState = 6;
_animationFrame = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptDeskClerk::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptDeskClerk::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptDeskClerk::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptDeskClerk::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptDeskClerk::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptDispatcher::AIScriptDispatcher(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptDispatcher::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptDispatcher::Update() {
return false;
}
void AIScriptDispatcher::TimerExpired(int timer) {
//return false;
}
void AIScriptDispatcher::CompletedMovementTrack() {
//return false;
}
void AIScriptDispatcher::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptDispatcher::ClickedByPlayer() {
//return false;
}
void AIScriptDispatcher::EnteredSet(int setId) {
// return false;
}
void AIScriptDispatcher::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptDispatcher::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptDispatcher::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptDispatcher::ShotAtAndMissed() {
// return false;
}
bool AIScriptDispatcher::ShotAtAndHit() {
return false;
}
void AIScriptDispatcher::Retired(int byActorId) {
// return false;
}
int AIScriptDispatcher::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptDispatcher::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptDispatcher::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptDispatcher::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptDispatcher::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptDispatcher::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptDispatcher::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptDispatcher::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,260 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptEarlyQBartender::AIScriptEarlyQBartender(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
// _varChooseIdleAnimation can have valid values: 0, 1
_varChooseIdleAnimation = 0;
_var2 = 1;
}
void AIScriptEarlyQBartender::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_varChooseIdleAnimation = 0;
_var2 = 1;
Actor_Put_In_Set(kActorEarlyQBartender, kSetNR05_NR08);
Actor_Set_At_XYZ(kActorEarlyQBartender, -717.0f, 0.0f, -468.0f, 416);
}
bool AIScriptEarlyQBartender::Update() {
return false;
}
void AIScriptEarlyQBartender::TimerExpired(int timer) {
//return false;
}
void AIScriptEarlyQBartender::CompletedMovementTrack() {
//return false;
}
void AIScriptEarlyQBartender::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptEarlyQBartender::ClickedByPlayer() {
//return false;
}
void AIScriptEarlyQBartender::EnteredSet(int setId) {
// return false;
}
void AIScriptEarlyQBartender::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptEarlyQBartender::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptEarlyQBartender::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptEarlyQBartender::ShotAtAndMissed() {
// return false;
}
bool AIScriptEarlyQBartender::ShotAtAndHit() {
return false;
}
void AIScriptEarlyQBartender::Retired(int byActorId) {
// return false;
}
int AIScriptEarlyQBartender::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptEarlyQBartender::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptEarlyQBartender::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationEarlyQBartenderWipingTable;
if (_animationFrame <= 5) {
_var2 = 1;
}
_animationFrame += _var2;
if (_animationFrame == 14 && !Random_Query(0, 1)) {
_var2 = -1;
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationEarlyQBartenderWipingTable)) {
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
} else if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationEarlyQBartenderWipingGlassIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationEarlyQBartenderWipingGlassIdle)) {
_animationFrame = 0;
if (!Random_Query(0, 6)) {
_varChooseIdleAnimation = 1;
}
}
}
break;
case 1:
*animation = kModelAnimationEarlyQBartenderCalmTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationEarlyQBartenderCalmTalk)) {
_animationFrame = 0;
}
}
break;
case 2:
#if BLADERUNNER_ORIGINAL_BUGS
// TODO A bug? This is identical to case 3 for animation 757, but 756 talk animation is left unused
*animation = kModelAnimationEarlyQBartenderDescribeTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationEarlyQBartenderDescribeTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationEarlyQBartenderCalmTalk;
}
#else
*animation = kModelAnimationEarlyQBartenderExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationEarlyQBartenderExplainTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationEarlyQBartenderCalmTalk;
}
#endif
break;
case 3:
*animation = kModelAnimationEarlyQBartenderDescribeTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationEarlyQBartenderDescribeTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationEarlyQBartenderCalmTalk;
}
break;
case 4:
*animation = kModelAnimationEarlyQBartenderPuttingAGlassOnTable;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationEarlyQBartenderPuttingAGlassOnTable)) {
Actor_Change_Animation_Mode(kActorEarlyQBartender, kAnimationModeIdle);
*animation = kModelAnimationEarlyQBartenderWipingGlassIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptEarlyQBartender::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptEarlyQBartender::ChangeAnimationMode(int mode) {
switch (mode) {
case 0:
_animationState = 0;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
_var2 = 1;
break;
case 3:
_animationState = 1;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 23:
_animationState = 4;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptEarlyQBartender::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptEarlyQBartender::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptEarlyQBartender::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptEarlyQBartender::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptEarlyQBartender::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,345 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptFishDealer::AIScriptFishDealer(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptFishDealer::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorFishDealer, kSetAR01_AR02);
Actor_Set_At_Waypoint(kActorFishDealer, 120, 424);
Actor_Set_Goal_Number(kActorFishDealer, 0);
}
bool AIScriptFishDealer::Update() {
#if BLADERUNNER_ORIGINAL_BUGS
if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorFishDealer) < 400
) {
Actor_Set_Goal_Number(kActorFishDealer, 400);
return true;
} else if (Player_Query_Current_Scene() == kSceneAR01
&& Actor_Query_Goal_Number(kActorFishDealer) != 1
&& Actor_Query_Goal_Number(kActorFishDealer) != 2
&& Actor_Query_Goal_Number(kActorFishDealer) != 400
) {
Actor_Set_Goal_Number(kActorFishDealer, 1);
return true;
}
return false;
#else
if (Global_Variable_Query(kVariableChapter) < 5) {
// prevent Fish Dealer from blinking out while McCoy is flying out from Animoid
if (Player_Query_Current_Scene() == kSceneAR01
&& Actor_Query_Goal_Number(kActorFishDealer) == 3
) {
Actor_Set_Goal_Number(kActorFishDealer, 1);
return true;
}
} else {
if (Actor_Query_Goal_Number(kActorFishDealer) < 400) {
Actor_Set_Goal_Number(kActorFishDealer, 400);
} else if (Actor_Query_In_Set(kActorFishDealer, kSetAR01_AR02)) {
// Remove the fish dealer from AR01 if she is still there in chapter 5,
// this can happen only with older save games.
GoalChanged(400, 400);
}
return true;
}
return false;
#endif // BLADERUNNER_ORIGINAL_BUGS
}
void AIScriptFishDealer::TimerExpired(int timer) {
//return false;
}
void AIScriptFishDealer::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorFishDealer) != 1)
return; // false
Actor_Set_Goal_Number(kActorFishDealer, 99); // A bug?
Actor_Set_Goal_Number(kActorFishDealer, 1);
//return true;
}
void AIScriptFishDealer::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptFishDealer::ClickedByPlayer() {
//return false;
}
void AIScriptFishDealer::EnteredSet(int setId) {
// return false;
}
void AIScriptFishDealer::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptFishDealer::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptFishDealer::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptFishDealer::ShotAtAndMissed() {
// return false;
}
bool AIScriptFishDealer::ShotAtAndHit() {
return false;
}
void AIScriptFishDealer::Retired(int byActorId) {
// return false;
}
int AIScriptFishDealer::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptFishDealer::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 1:
AI_Movement_Track_Flush(kActorFishDealer);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 121, Random_Query(2, 5), 720);
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 122, Random_Query(3, 6), 640);
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 120, Random_Query(6, 6), 640);
} else {
int randFace;
if (Random_Query(1, 3) == 2) {
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 122, Random_Query(5, 8), 720);
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 120, Random_Query(2, 4), 640);
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 121, Random_Query(5, 7), 640);
randFace = Random_Query(5, 10);
} else {
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 122, Random_Query(3, 5), 720);
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 121, Random_Query(3, 3), 640);
randFace = Random_Query(3, 3);
}
AI_Movement_Track_Append_With_Facing(kActorFishDealer, 120, randFace, 640);
}
AI_Movement_Track_Repeat(kActorFishDealer);
return true;
case 2:
AI_Movement_Track_Flush(kActorFishDealer);
AI_Movement_Track_Append(kActorFishDealer, 120, 30);
AI_Movement_Track_Repeat(kActorFishDealer);
return true;
case 3:
AI_Movement_Track_Flush(kActorFishDealer);
AI_Movement_Track_Append(kActorFishDealer, 39, 0);
AI_Movement_Track_Repeat(kActorFishDealer);
return true;
case 400:
#if !BLADERUNNER_ORIGINAL_BUGS
// Movement truck is not reset and she might end-up showing up in AR01 after all.
// This will lead to a issue with CDFRAMES in chapter 5
AI_Movement_Track_Flush(kActorFishDealer);
#endif
Actor_Put_In_Set(kActorFishDealer, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorFishDealer, 40, 0);
return true;
default:
return false;
}
return false;
}
bool AIScriptFishDealer::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationFishDealerIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationFishDealerIdle))
_animationFrame = 0;
break;
case 1:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationFishDealerIdle;
_animationState = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
*animation = kModelAnimationFishDealerCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationFishDealerCalmTalk))
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationFishDealerExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationFishDealerExplainTalk)) {
_animationFrame = 0;
_animationState = 2;
}
break;
case 3:
*animation = kModelAnimationFishDealerNoTroubleTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationFishDealerNoTroubleTalk)) {
_animationFrame = 0;
_animationState = 3;
}
break;
case 4:
*animation = kModelAnimationFishDealerGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationFishDealerGestureGive)) {
*animation = kModelAnimationFishDealerIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 5:
*animation = kModelAnimationFishDealerWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationFishDealerWalking))
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptFishDealer::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptFishDealer::ChangeAnimationMode(int mode) {
switch (mode) {
case 0:
if (_animationState > 3) {
_animationState = 0;
_animationFrame = 0;
} else {
_resumeIdleAfterFramesetCompletesFlag = true;
}
break;
case 1:
_animationState = 5;
_animationFrame = 0;
break;
case 3:
// fall through
case 14:
// fall through
case 15:
// fall through
case 16:
// fall through
case 17:
// fall through
case 18:
// fall through
case 19:
_animationState = Random_Query(0, 2) + 1;
_animationFrame = 0;
break;
case 12:
_animationState = 2;
_animationFrame = 0;
break;
case 13:
_animationState = 3;
_animationFrame = 0;
break;
case 23:
_animationState = 4;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptFishDealer::ChangeAnimationMode(%d) - Target mode is not supported", mode);
return true;
}
return true;
}
void AIScriptFishDealer::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptFishDealer::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptFishDealer::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptFishDealer::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,897 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
//#include "common/debug.h"
namespace BladeRunner {
AIScriptFreeSlotA::AIScriptFreeSlotA(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_var1 = 0;
_var2 = 1;
_fallSpeed = 0.0f;
_fallHeightCurrent = 0.0f; // not initialized in original
_fallHeightTarget = 0.0f; // not initialized in original
}
void AIScriptFreeSlotA::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_var1 = 0;
_var2 = 1;
_fallSpeed = 0.0f;
_fallHeightCurrent = 0.0f; // not initialized in original
_fallHeightTarget = 0.0f; // not initialized in original
World_Waypoint_Set(525, kSetKP02, -780.0f, -615.49f, 2611.0f);
// TODO: A bug? world waypoint 526 is unused
World_Waypoint_Set(526, kSetKP02, -780.0f, -615.49f, 2759.0f);
}
bool AIScriptFreeSlotA::Update() {
switch (Global_Variable_Query(kVariableChapter)) {
case 4:
// Act 4
if (Actor_Query_Which_Set_In(kActorMcCoy) == kSetUG15
&& Actor_Query_Which_Set_In(kActorFreeSlotA) == kSetUG15
) {
int goal = Actor_Query_Goal_Number(kActorFreeSlotA);
if ((goal == kGoalFreeSlotAUG15RunToOtherSide
|| goal == kGoalFreeSlotAUG15RunBack)
&& Actor_Query_Inch_Distance_From_Actor(kActorFreeSlotA, kActorMcCoy) <= 48
) {
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAUG15Attack);
} else if (goal == kGoalFreeSlotAUG15Fall) {
float x, y, z;
Actor_Query_XYZ(kActorMcCoy, &x, &y, &z);
_fallHeightCurrent += _fallSpeed;
if (_fallHeightTarget < _fallHeightCurrent) {
_fallSpeed -= 0.2f;
} else {
_fallHeightCurrent = _fallHeightTarget;
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotADefault);
}
Actor_Set_At_XYZ(kActorFreeSlotA, x, _fallHeightCurrent, z, Actor_Query_Facing_1024(kActorFreeSlotA));
}
return true;
}
switch (Actor_Query_Goal_Number(kActorFreeSlotA)) {
case kGoalFreeSlotAWalkAround:
#if BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_Which_Set_In(kActorFreeSlotA) == Player_Query_Current_Set()
&& Actor_Query_Inch_Distance_From_Actor(kActorFreeSlotA, kActorMcCoy) <= 48
) {
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAttackMcCoy);
}
#else
if (Actor_Query_Which_Set_In(kActorFreeSlotA) == Player_Query_Current_Set()
&& Actor_Query_Inch_Distance_From_Actor(kActorFreeSlotA, kActorMcCoy) <= 54
) {
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAttackMcCoy);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case kGoalFreeSlotAAttackMcCoy:
if (Actor_Query_Which_Set_In(kActorFreeSlotA) != Player_Query_Current_Set()) {
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAWalkAround);
}
break;
case kGoalFreeSlotAGone:
if (Actor_Query_Which_Set_In(kActorFreeSlotA) != Player_Query_Current_Set()) {
Game_Flag_Reset(kFlagRatWalkingAround);
Game_Flag_Reset(kFlagUG15BridgeWillBreak);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotADefault);
#else
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGoneIntermediate);
#endif
}
break;
default:
if (!Game_Flag_Query(kFlagRatWalkingAround)) {
Game_Flag_Set(kFlagRatWalkingAround);
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAWalkAround);
Actor_Set_Targetable(kActorFreeSlotA, true);
}
}
return true;
case 5:
// Act 5
if (Actor_Query_Goal_Number(kActorFreeSlotA) < kGoalFreeSlotAAct5Default) {
AI_Movement_Track_Flush(kActorFreeSlotA);
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5Default);
} else {
#if BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_Goal_Number(kActorFreeSlotA) == kGoalFreeSlotAAct5Prepare
&& Actor_Query_Which_Set_In(kActorMcCoy) == kSetKP02
) {
Actor_Set_Targetable(kActorFreeSlotA, true);
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5KP02Attack);
}
#else
// copying the behavior of Rat B (kActorFreeSlotB) because it works without the bug
// Fixes the bug where the Rat A is killed in KP02 but when McCoy re-enters it is there alive
// in idle mode and non-target-able
if (Actor_Query_Goal_Number(kActorFreeSlotA) != kGoalFreeSlotAAct5Prepare
|| Actor_Query_Which_Set_In(kActorMcCoy) != kSetKP02
) {
if (Actor_Query_Goal_Number(kActorFreeSlotA) == kGoalFreeSlotAGone) {
if (Actor_Query_Which_Set_In(kActorFreeSlotA) != Player_Query_Current_Set()) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotA);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5Default);
#else
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGoneIntermediate);
#endif
return true;
}
}
return false;
}
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5KP02Attack);
Actor_Set_Targetable(kActorFreeSlotA, true);
return true;
#endif // BLADERUNNER_ORIGINAL_BUGS
}
return true;
default:
return false;
}
}
void AIScriptFreeSlotA::TimerExpired(int timer) {
//return false;
}
void AIScriptFreeSlotA::CompletedMovementTrack() {
// debug("Rat A completed move with Goal: %d", Actor_Query_Goal_Number(kActorFreeSlotA));
switch (Actor_Query_Goal_Number(kActorFreeSlotA)) {
case kGoalFreeSlotAUG15WalkOut:
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAUG15RunToOtherSide);
break;
case kGoalFreeSlotAUG15RunToOtherSide:
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAUG15RunBack);
break;
case kGoalFreeSlotAUG15RunBack:
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAUG15Wait);
break;
case kGoalFreeSlotAWalkAround:
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAWalkAroundRestart);
break;
case kGoalFreeSlotAWalkAroundRestart:
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAWalkAround);
break;
case kGoalFreeSlotAAct5Default:
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5Prepare);
break;
case kGoalFreeSlotAAct5KP02Attack:
Non_Player_Actor_Combat_Mode_On(kActorFreeSlotA, kActorCombatStateIdle, false, kActorMcCoy, 8, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 5, 300, false);
break;
default:
return; //false;
}
return; //true;
}
void AIScriptFreeSlotA::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptFreeSlotA::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorFreeSlotA) == kGoalFreeSlotAGone) {
Actor_Face_Actor(kActorMcCoy, kActorFreeSlotA, true);
if (_vm->_cutContent && !Game_Flag_Query(kFlagMcCoyCommentsOnHoodooRats)) {
Game_Flag_Set(kFlagMcCoyCommentsOnHoodooRats);
// Note: Quote 1060 mentions "Hoodoo Rats". Quote 1070 is *boop* in ENG version.
// However, quote 1070 is similar to 1060 quote in FRA, DEU, ESP and ITA versions
// with the only difference being not mentioning the "Hoodoo Rats" name.
// It uses a generic "rats" in its place.
// For those four languages one of the two quotes will play (random chance 50%)
if ((_vm->_language == Common::DE_DEU
|| _vm->_language == Common::ES_ESP
|| _vm->_language == Common::FR_FRA
|| _vm->_language == Common::IT_ITA)
&& (Random_Query(1, 2) == 1)) {
Actor_Voice_Over(1070, kActorVoiceOver); // "rats"
} else {
Actor_Voice_Over(1060, kActorVoiceOver); // "Hoodoo rats"
}
Actor_Voice_Over(1080, kActorVoiceOver);
Actor_Voice_Over(1090, kActorVoiceOver);
} else {
if (Random_Query(1, 2) == 1) {
Actor_Says(kActorMcCoy, 8655, 16);
} else {
Actor_Says(kActorMcCoy, 8665, 16);
}
}
}
//return false;
}
void AIScriptFreeSlotA::EnteredSet(int setId) {
// return false;
}
void AIScriptFreeSlotA::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptFreeSlotA::OtherAgentExitedThisSet(int otherActorId) {
#if !BLADERUNNER_ORIGINAL_BUGS
if (otherActorId == kActorMcCoy && Actor_Query_Goal_Number(kActorFreeSlotA) == kGoalFreeSlotAGone) {
if (Global_Variable_Query(kVariableChapter) == 4) {
Game_Flag_Reset(kFlagRatWalkingAround);
Game_Flag_Reset(kFlagUG15BridgeWillBreak);
} else if (Global_Variable_Query(kVariableChapter) == 5) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotA);
}
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGoneIntermediate);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// return false;
}
void AIScriptFreeSlotA::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptFreeSlotA::ShotAtAndMissed() {
if (Actor_Query_In_Set(kActorFreeSlotA, kSetUG15)) {
checkIfOnBridge();
}
}
bool AIScriptFreeSlotA::ShotAtAndHit() {
if (Actor_Query_In_Set(kActorFreeSlotA, kSetUG15)) {
checkIfOnBridge();
// This goal "kGoalFreeSlotAUG15Die" circumvents the proper process
// a proper combat with the rat and it dying when its health reaches <= 0
// ie. being "retired".
// Thus, since the rat never actually 'dies' from being shot,
// its Actor::retire() is not called in this case (UG15 bridge rat),
// and so its bounding box is not affected. Thus, the rat corpse remains clickable.
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAUG15Die);
return true;
}
return false;
}
void AIScriptFreeSlotA::Retired(int byActorId) {
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGone);
}
int AIScriptFreeSlotA::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptFreeSlotA::GoalChanged(int currentGoalNumber, int newGoalNumber) {
// debug("Rat A goal changed from %d to: %d", currentGoalNumber, newGoalNumber);
switch (newGoalNumber) {
case kGoalFreeSlotAUG15Wait:
AI_Movement_Track_Flush(kActorFreeSlotA);
Actor_Change_Animation_Mode(kActorFreeSlotA, kAnimationModeIdle);
Actor_Set_Targetable(kActorFreeSlotA, false);
break;
case kGoalFreeSlotAUG15WalkOut:
// kSetUG15
Actor_Force_Stop_Walking(kActorMcCoy);
AI_Movement_Track_Flush(kActorFreeSlotA);
World_Waypoint_Set(444, kSetUG15, -48.75f, 44.66f, 87.57f);
AI_Movement_Track_Append(kActorFreeSlotA, 444, 1);
AI_Movement_Track_Repeat(kActorFreeSlotA);
break;
case kGoalFreeSlotAUG15RunToOtherSide:
// kSetUG15
AI_Movement_Track_Flush(kActorFreeSlotA);
World_Waypoint_Set(444, kSetUG15, -237.0f, 48.07f, 208.0f);
AI_Movement_Track_Append(kActorFreeSlotA, 444, 1);
AI_Movement_Track_Repeat(kActorFreeSlotA);
Actor_Set_Targetable(kActorFreeSlotA, true);
break;
case kGoalFreeSlotAUG15RunBack:
// kSetUG15
AI_Movement_Track_Flush(kActorFreeSlotA);
World_Waypoint_Set(444, kSetUG15, 3.52f, 52.28f, 90.68f);
AI_Movement_Track_Append(kActorFreeSlotA, 444, 0);
AI_Movement_Track_Repeat(kActorFreeSlotA);
break;
case kGoalFreeSlotAUG15Attack:
Player_Loses_Control();
Actor_Force_Stop_Walking(kActorMcCoy);
AI_Movement_Track_Flush(kActorFreeSlotA);
Actor_Face_Actor(kActorFreeSlotA, kActorMcCoy, true);
Actor_Change_Animation_Mode(kActorFreeSlotA, kAnimationModeCombatAttack);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
break;
case kGoalFreeSlotAUG15Die:
AI_Movement_Track_Flush(kActorFreeSlotA);
Actor_Set_Targetable(kActorFreeSlotA, false);
Game_Flag_Set(kFlagUG15RatShot);
_animationState = 7;
_animationFrame = 0;
break;
case kGoalFreeSlotAWalkAround:
AI_Movement_Track_Flush(kActorFreeSlotA);
goToRandomUGxx();
AI_Movement_Track_Repeat(kActorFreeSlotA);
break;
case kGoalFreeSlotAWalkAroundRestart:
// kSetFreeSlotG
AI_Movement_Track_Flush(kActorFreeSlotA);
AI_Movement_Track_Append(kActorFreeSlotA, 39, 1);
AI_Movement_Track_Repeat(kActorFreeSlotA);
break;
case kGoalFreeSlotAAttackMcCoy:
Actor_Set_Targetable(kActorFreeSlotA, true);
Non_Player_Actor_Combat_Mode_On(kActorFreeSlotA, kActorCombatStateIdle, false, kActorMcCoy, 8, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 25, 0, 75, 5, 300, false);
break;
case kGoalFreeSlotAUG15Fall:
Actor_Force_Stop_Walking(kActorFreeSlotA);
AI_Movement_Track_Flush(kActorFreeSlotA);
_fallHeightCurrent = 52.46f;
_fallSpeed = -4.0f;
_fallHeightTarget = -10.0f;
if (_animationState != 7
&& _animationState != 8
) {
_animationState = 7;
_animationFrame = 0;
}
break;
case kGoalFreeSlotAUG15Prepare:
AI_Movement_Track_Flush(kActorFreeSlotA);
Actor_Put_In_Set(kActorFreeSlotA, kSetUG15);
Actor_Set_At_XYZ(kActorFreeSlotA, 3.52f, 52.28f, 90.68f, 700);
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAUG15Wait);
break;
case kGoalFreeSlotAAct5Default:
// kSetFreeSlotG
AI_Movement_Track_Append(kActorFreeSlotA, 39, 0);
AI_Movement_Track_Repeat(kActorFreeSlotA);
break;
case kGoalFreeSlotAAct5KP02Attack:
// kSetKP02
AI_Movement_Track_Flush(kActorFreeSlotA);
AI_Movement_Track_Append(kActorFreeSlotA, 525, 0);
AI_Movement_Track_Repeat(kActorFreeSlotA);
break;
#if BLADERUNNER_ORIGINAL_BUGS
#else
case kGoalFreeSlotAGoneIntermediate:
Actor_Set_Health(kActorFreeSlotA, 20, 20);
if (Global_Variable_Query(kVariableChapter) == 4) {
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotADefault);
} else if (Global_Variable_Query(kVariableChapter) == 5) {
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAAct5Default);
}
break;
#endif
case kGoalFreeSlotAGone:
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Health(kActorFreeSlotA, 20, 20);
#endif
// A bug? What does this friendliness affect?
Actor_Set_Friendliness_To_Other(kActorFreeSlotA, kActorMcCoy, 40);
break;
default:
return false;
}
return true;
}
bool AIScriptFreeSlotA::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationRatIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationRatSlowWalk;
if (_var1) {
--_var1;
} else {
_animationFrame += _var2;
if (_animationFrame < 8) {
_var2 = 1;
} else {
if (_animationFrame > 8) {
_var2 = -1;
} else if (Random_Query(0, 4)) {
_var2 = -_var2;
}
}
if (_animationFrame >= 7 && _animationFrame <= 9) {
_var1 = Random_Query(0, 1);
}
}
break;
case 2:
*animation = kModelAnimationRatSlowWalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatSlowWalk) - 1) {
*animation = kModelAnimationRatIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 3:
*animation = kModelAnimationRatRunning;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatRunning)) {
_animationFrame = 0;
}
break;
case 4:
*animation = kModelAnimationRatJumpAttack;
++_animationFrame;
if (_animationFrame == 1) {
int snd;
if (Random_Query(1, 2) == 1) {
snd = 9010;
} else {
snd = 9015;
}
Sound_Play_Speech_Line(kActorFreeSlotA, snd, 75, 0, 99);
}
if (_animationFrame == 3) {
Ambient_Sounds_Play_Sound(kSfxRATTY4, 99, 0, 0, 20);
Actor_Combat_AI_Hit_Attempt(kActorFreeSlotA);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatJumpAttack)) {
_animationState = 0;
_animationFrame = 0;
Actor_Change_Animation_Mode(kActorFreeSlotA, kAnimationModeCombatIdle);
}
break;
case 5:
// This is an animation for Maggie (exploding) but is also used for generic death states (rats, generic walkers)
// probably for debug purposes
*animation = kModelAnimationMaggieExploding;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieExploding) - 1) {
Actor_Change_Animation_Mode(kActorFreeSlotA, kAnimationModeIdle);
}
break;
case 6:
if (_animationFrame == 1) {
Ambient_Sounds_Play_Sound(kSfxRATTY3, 99, 0, 0, 20);
}
*animation = kModelAnimationRatHurt;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatHurt)) {
_animationFrame = 0;
_animationState = 0;
Actor_Change_Animation_Mode(kActorFreeSlotA, kAnimationModeIdle);
}
break;
case 7:
*animation = kModelAnimationRatDying;
++_animationFrame;
if (_animationFrame == 1) {
Ambient_Sounds_Play_Sound(kSfxRATTY5, 99, 0, 0, 25);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1) {
// -1 in the clause is ok here since the next _animationState is 8 which will maintain the last frame (Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1)
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1;
_animationState = 8;
Actor_Set_Goal_Number(kActorFreeSlotA, kGoalFreeSlotAGone);
}
break;
case 8:
*animation = kModelAnimationRatDying;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptFreeSlotA::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptFreeSlotA::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if ((unsigned int)(_animationState - 1) > 1) {
_animationState = 0;
_animationFrame = 0;
} else if (_animationState == 1) {
_animationState = 2;
}
break;
case kAnimationModeWalk:
_animationState = 3;
_animationFrame = 0;
break;
case 4:
if ((unsigned int)(_animationState - 1) > 1) {
_animationState = 0;
_animationFrame = 0;
} else if (_animationState == 1) {
_animationState = 2;
}
break;
case 6:
_animationState = 4;
_animationFrame = 0;
break;
case 7:
_animationState = 3;
_animationFrame = 0;
break;
case 8:
_animationState = 3;
_animationFrame = 0;
break;
case 21:
_animationState = 6;
_animationFrame = 0;
break;
case 43:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 7;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptFreeSlotA::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptFreeSlotA::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptFreeSlotA::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptFreeSlotA::ReachedMovementTrackWaypoint(int waypointId) {
if (Actor_Query_Which_Set_In(kActorFreeSlotA) == kSetUG01) {
if (waypointId == 465) {
Actor_Change_Animation_Mode(kActorFreeSlotA, 43);
}
} else if (Actor_Query_Goal_Number(kActorFreeSlotA) == kGoalFreeSlotAUG15RunToOtherSide) {
Actor_Face_Actor(kActorFreeSlotA, kActorMcCoy, true);
}
return true;
}
void AIScriptFreeSlotA::FledCombat() {
// return false;
}
void AIScriptFreeSlotA::checkIfOnBridge() {
if (_vm->_cutContent && Query_Difficulty_Level() == kGameDifficultyEasy) {
// Make the bridge indestructible on easy mode for the enhanced version
return;
}
float x, y, z;
Actor_Query_XYZ(kActorFreeSlotA, &x, &y, &z);
// bug? this should probably check if McCoy is close enough because bridge will break long after rat died and player tries to walk through
if (-150.0 <= x && x < -30.0f) {
Game_Flag_Set(kFlagUG15BridgeWillBreak);
}
}
void AIScriptFreeSlotA::goToRandomUGxx() {
switch (Random_Query(1, 14)) {
case 1:
// kSetUG01
#if BLADERUNNER_ORIGINAL_BUGS
AI_Movement_Track_Append(kActorFreeSlotA, 450, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 451, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 450, 0);
break;
#else
// Don't put rats in UG01 when Lucy is also here
if (!Actor_Query_In_Set(kActorLucy, kSetUG01)) {
AI_Movement_Track_Append(kActorFreeSlotA, 450, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 451, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 450, 0);
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 2:
// kSetUG01
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(463, kSetUG01, 144.98f, -50.13f, -175.75f);
World_Waypoint_Set(464, kSetUG01, 105.6f, -50.13f, -578.46f);
World_Waypoint_Set(465, kSetUG01, 62.0f, -50.13f, -574.0f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 5);
break;
#else
// Don't put rats in UG01 when Lucy is also here
if (!Actor_Query_In_Set(kActorLucy, kSetUG01)) {
World_Waypoint_Set(463, kSetUG01, 144.98f, -50.13f, -175.75f);
World_Waypoint_Set(464, kSetUG01, 105.6f, -50.13f, -578.46f);
World_Waypoint_Set(465, kSetUG01, 62.0f, -50.13f, -574.0f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 5);
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 3:
// kSetUG04
AI_Movement_Track_Append(kActorFreeSlotA, 446, 15);
AI_Movement_Track_Append(kActorFreeSlotA, 447, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 449, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 448, 2);
AI_Movement_Track_Append(kActorFreeSlotA, 449, 0);
break;
case 4:
// kSetUG04
World_Waypoint_Set(463, kSetUG04, -22.7f, 6.39f, 33.12f);
World_Waypoint_Set(464, kSetUG04, -6.70f, -1.74f, -362.88f);
World_Waypoint_Set(465, kSetUG04, 164.0f, 11.87f, -1013.0f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 2);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 0);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 0);
break;
case 5:
// kSetUG05
AI_Movement_Track_Append(kActorFreeSlotA, 457, 15);
AI_Movement_Track_Append(kActorFreeSlotA, 458, 0);
AI_Movement_Track_Append(kActorFreeSlotA, 459, 15);
break;
case 6:
// kSetUG06
AI_Movement_Track_Append(kActorFreeSlotA, 460, 15);
AI_Movement_Track_Append(kActorFreeSlotA, 461, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 460, 15);
break;
case 7:
// kSetUG07 or kSetFreeSlotG
#if BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_In_Set(kActorClovis, kSetUG07)) {
// this check is not very effective since Clovis
// will spawn in the set when McCoy goes to the downwards exit
// at which point a rat may already be in the set and that could
// make them collide with Clovis' path
AI_Movement_Track_Append(kActorFreeSlotA, 39, 10); // kSetFreeSlotG
} else {
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
// TODO: A bug? the waypoint 465 is created but is unused
}
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
// TODO: A bug? the waypoint 465 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 8:
// kSetUG07
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
// TODO: A bug? the waypoint 465 is created but is unused
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
// TODO: A bug? the waypoint 465 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 9:
// kSetUG07
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 1);
// TODO: A bug? the waypoint 463 is created but is unused
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 1);
// TODO: A bug? the waypoint 463 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 10:
// kSetUG07
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
// TODO: A bug? the waypoint 463 is created but is unused
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(463, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(464, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(465, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
// TODO: A bug? the waypoint 463 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 11:
// kSetUG09
World_Waypoint_Set(463, kSetUG09, 91.0f, 156.94f, -498.0f);
World_Waypoint_Set(464, kSetUG09, -149.0f, 156.94f, -498.0f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
break;
case 12:
// kSetUG09
World_Waypoint_Set(463, kSetUG09, 91.0f, 156.94f, -498.0f);
World_Waypoint_Set(464, kSetUG09, -149.0f, 156.94f, -498.0f);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 5);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
break;
case 13:
// kSetUG09
#if BLADERUNNER_ORIGINAL_BUGS
// this makes the rat appear on the pipe (top left) but this is buggy
// since it appears floating there
World_Waypoint_Set(463, kSetUG09, -152.51f, 277.31f, 311.98f);
World_Waypoint_Set(464, kSetUG09, -124.51f, 275.08f, 319.98f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 8);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
#else
// replacing with something more normal
World_Waypoint_Set(463, kSetUG09, 91.0f, 156.94f, -498.0f);
World_Waypoint_Set(464, kSetUG09, -29.60f, 156.94f, -498.0f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
#endif
break;
case 14:
// kSetUG12
World_Waypoint_Set(463, kSetUG12, -360.67f, 21.39f, 517.55f);
World_Waypoint_Set(464, kSetUG12, -250.67f, 21.39f, 477.55f);
World_Waypoint_Set(465, kSetUG12, -248.67f, 21.39f, -1454.45f);
AI_Movement_Track_Append(kActorFreeSlotA, 463, 1);
AI_Movement_Track_Append(kActorFreeSlotA, 464, 8);
AI_Movement_Track_Append(kActorFreeSlotA, 465, 1);
break;
default:
// kSetFreeSlotG
AI_Movement_Track_Append(kActorFreeSlotA, 39, Random_Query(1, 10));
break;
}
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,738 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
//#include "common/debug.h"
namespace BladeRunner {
AIScriptFreeSlotB::AIScriptFreeSlotB(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_var1 = 0;
_var2 = 1;
}
void AIScriptFreeSlotB::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_var1 = 0;
_var2 = 1;
World_Waypoint_Set(527, kSetKP02, -468.46f, -616.58f, 2840.60f);
// TODO: A bug? world waypoints 528, 529 are unused
World_Waypoint_Set(528, kSetKP02, -1024.46f, -615.49f, 2928.60f);
World_Waypoint_Set(529, kSetKP02, -1024.46f, -615.49f, 2788.60f);
}
bool AIScriptFreeSlotB::Update() {
if (Global_Variable_Query(kVariableChapter) > 5) {
return false;
}
if (Global_Variable_Query(kVariableChapter) == 4) {
switch (Actor_Query_Goal_Number(kActorFreeSlotB)) {
case kGoalFreeSlotBAct4Default:
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4WalkAround);
Actor_Set_Targetable(kActorFreeSlotB, true);
break;
case kGoalFreeSlotBAct4WalkAround:
#if BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_Which_Set_In(kActorFreeSlotB) == Player_Query_Current_Set()
&& Actor_Query_Inch_Distance_From_Actor(kActorFreeSlotB, kActorMcCoy) <= 48
) {
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4AttackMcCoy);
}
#else
if (Actor_Query_Which_Set_In(kActorFreeSlotB) == Player_Query_Current_Set()
&& Actor_Query_Inch_Distance_From_Actor(kActorFreeSlotB, kActorMcCoy) <= 54
) {
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4AttackMcCoy);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case kGoalFreeSlotBAct4AttackMcCoy:
if (Actor_Query_Which_Set_In(kActorFreeSlotB) != Player_Query_Current_Set()) {
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4WalkAround);
}
break;
case kGoalFreeSlotBGone:
if (Actor_Query_Which_Set_In(kActorFreeSlotB) != Player_Query_Current_Set()) {
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4Default);
#else
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBGoneIntermediate);
#endif
}
break;
default:
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4Default);
break;
}
return false;
}
// if in Act 5
if (Actor_Query_Goal_Number(kActorFreeSlotB) < kGoalFreeSlotBAct5Default) {
AI_Movement_Track_Flush(kActorFreeSlotB);
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5Default);
return true;
} else {
if (Actor_Query_Goal_Number(kActorFreeSlotB) != kGoalFreeSlotBAct5Prepare
|| Actor_Query_Which_Set_In(kActorMcCoy) != kSetKP02
) {
if (Actor_Query_Goal_Number(kActorFreeSlotB) == kGoalFreeSlotBGone) {
if (Actor_Query_Which_Set_In(kActorFreeSlotB) != Player_Query_Current_Set()) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotB);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5Default);
#else
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBGoneIntermediate);
#endif
return true;
}
}
return false;
}
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5KP02Attack);
Actor_Set_Targetable(kActorFreeSlotB, true);
return true;
}
}
void AIScriptFreeSlotB::TimerExpired(int timer) {
//return false;
}
void AIScriptFreeSlotB::CompletedMovementTrack() {
// debug("Rat B completed move with Goal: %d", Actor_Query_Goal_Number(kActorFreeSlotB));
switch (Actor_Query_Goal_Number(kActorFreeSlotB)) {
case kGoalFreeSlotBAct4Default:
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4WalkAround);
break;
case kGoalFreeSlotBAct4WalkAround:
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4Default);
break;
case kGoalFreeSlotBAct5Default:
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5Prepare);
break;
case kGoalFreeSlotBAct5KP02Attack:
Non_Player_Actor_Combat_Mode_On(kActorFreeSlotB, kActorCombatStateIdle, false, kActorMcCoy, 8, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 5, 300, false);
break;
default:
return; //false;
}
return; //true;
}
void AIScriptFreeSlotB::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptFreeSlotB::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorFreeSlotB) != kGoalFreeSlotBGone)
return; //false;
Actor_Face_Actor(kActorMcCoy, kActorFreeSlotB, true);
if (_vm->_cutContent && !Game_Flag_Query(kFlagMcCoyCommentsOnHoodooRats)) {
Game_Flag_Set(kFlagMcCoyCommentsOnHoodooRats);
// Note: Quote 1060 mentions "Hoodoo Rats". Quote 1070 is *boop* in ENG version.
// However, quote 1070 is similar to 1060 quote in FRA, DEU, ESP and ITA versions
// with the only difference being not mentioning the "Hoodoo Rats" name.
// It uses a generic "rats" in its place.
// For those four languages one of the two quotes will play (random chance 50%)
if ((_vm->_language == Common::DE_DEU
|| _vm->_language == Common::ES_ESP
|| _vm->_language == Common::FR_FRA
|| _vm->_language == Common::IT_ITA)
&& (Random_Query(1, 2) == 1)) {
Actor_Voice_Over(1070, kActorVoiceOver); // "rats"
} else {
Actor_Voice_Over(1060, kActorVoiceOver); // "Hoodoo rats"
}
Actor_Voice_Over(1080, kActorVoiceOver);
Actor_Voice_Over(1090, kActorVoiceOver);
} else {
if (Random_Query(1, 2) == 1) {
Actor_Says(kActorMcCoy, 8655, 16);
} else {
Actor_Says(kActorMcCoy, 8665, 16);
}
}
}
void AIScriptFreeSlotB::EnteredSet(int setId) {
// return false;
}
void AIScriptFreeSlotB::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptFreeSlotB::OtherAgentExitedThisSet(int otherActorId) {
#if !BLADERUNNER_ORIGINAL_BUGS
if (otherActorId == kActorMcCoy && Actor_Query_Goal_Number(kActorFreeSlotB) == kGoalFreeSlotBGone) {
if (Global_Variable_Query(kVariableChapter) == 5) {
Non_Player_Actor_Combat_Mode_Off(kActorFreeSlotB);
}
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBGoneIntermediate);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// return false;
}
void AIScriptFreeSlotB::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptFreeSlotB::ShotAtAndMissed() {
// return false;
}
bool AIScriptFreeSlotB::ShotAtAndHit() {
return false;
}
void AIScriptFreeSlotB::Retired(int byActorId) {
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBGone);
}
int AIScriptFreeSlotB::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptFreeSlotB::GoalChanged(int currentGoalNumber, int newGoalNumber) {
// debug("Rat B goal changed from %d to: %d", currentGoalNumber, newGoalNumber);
switch (newGoalNumber) {
case kGoalFreeSlotBAct4Default:
// kSetFreeSlotG
AI_Movement_Track_Flush(kActorFreeSlotB);
AI_Movement_Track_Append(kActorFreeSlotB, 39, 2);
AI_Movement_Track_Repeat(kActorFreeSlotB);
break;
case kGoalFreeSlotBAct4WalkAround:
AI_Movement_Track_Flush(kActorFreeSlotB);
goToRandomUGxx();
AI_Movement_Track_Repeat(kActorFreeSlotB);
break;
case kGoalFreeSlotBAct4AttackMcCoy:
Actor_Set_Targetable(kActorFreeSlotB, true);
Non_Player_Actor_Combat_Mode_On(kActorFreeSlotB, kActorCombatStateIdle, false, kActorMcCoy, 8, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 25, 0, 75, 5, 300, false);
break;
case kGoalFreeSlotBAct5Default:
// kSetFreeSlotG
AI_Movement_Track_Append(kActorFreeSlotB, 39, 0);
AI_Movement_Track_Repeat(kActorFreeSlotB);
break;
case kGoalFreeSlotBAct5KP02Attack:
// kSetKP02
AI_Movement_Track_Flush(kActorFreeSlotB);
AI_Movement_Track_Append(kActorFreeSlotB, 527, 0);
AI_Movement_Track_Repeat(kActorFreeSlotB);
break;
#if BLADERUNNER_ORIGINAL_BUGS
#else
case kGoalFreeSlotBGoneIntermediate:
Actor_Set_Health(kActorFreeSlotB, 20, 20);
if (Global_Variable_Query(kVariableChapter) == 4) {
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct4Default);
} else if (Global_Variable_Query(kVariableChapter) == 5) {
Actor_Set_Goal_Number(kActorFreeSlotB, kGoalFreeSlotBAct5Default);
}
break;
#endif
case kGoalFreeSlotBGone:
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Health(kActorFreeSlotB, 20, 20);
#endif
break;
default:
return false;
}
return true;
}
bool AIScriptFreeSlotB::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationRatIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationRatSlowWalk;
if (_var1) {
--_var1;
} else {
_animationFrame += _var2;
if (_animationFrame < 8) {
_var2 = 1;
} else {
if (_animationFrame > 8) {
_var2 = -1;
} else if (Random_Query(0, 4)) {
_var2 = -_var2;
}
}
if (_animationFrame >= 7 && _animationFrame <= 9) {
_var1 = Random_Query(0, 1);
}
}
break;
case 2:
*animation = kModelAnimationRatSlowWalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatSlowWalk) - 1) {
*animation = kModelAnimationRatIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 3:
*animation = kModelAnimationRatRunning;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatRunning)) {
_animationFrame = 0;
}
break;
case 4:
*animation = kModelAnimationRatJumpAttack;
++_animationFrame;
if (_animationFrame == 3) {
int snd;
if (Random_Query(1, 2) == 1) {
snd = 9010;
} else {
snd = 9015;
}
Sound_Play_Speech_Line(kActorFreeSlotB, snd, 75, 0, 99);
}
if (_animationFrame == 3) {
Actor_Combat_AI_Hit_Attempt(kActorFreeSlotB);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelAnimationRatIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 5:
// This is an animation for Maggie (exploding) but is also used for generic death states (rats, generic walkers)
// probably for debug purposes
*animation = kModelAnimationMaggieExploding;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieExploding) - 1) {
_animationState = 8;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieExploding) - 1;
}
break;
case 6:
if (_animationFrame == 1) {
Ambient_Sounds_Play_Sound(kSfxRATTY3, 99, 0, 0, 20);
}
*animation = kModelAnimationRatHurt;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatHurt)) {
_animationFrame = 0;
_animationState = 0;
Actor_Change_Animation_Mode(kActorFreeSlotB, kAnimationModeIdle);
}
break;
case 7:
*animation = kModelAnimationRatDying;
++_animationFrame;
if (_animationFrame == 1) {
Ambient_Sounds_Play_Sound(kSfxRATTY5, 99, 0, 0, 25);
}
#if BLADERUNNER_ORIGINAL_BUGS
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1;
}
_animationState = 8;
#else
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1;
_animationState = 8;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case 8:
*animation = kModelAnimationRatDying;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationRatDying) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptFreeSlotB::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptFreeSlotB::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if ((unsigned int)(_animationState - 1) > 1) {
_animationState = 0;
_animationFrame = 0;
} else if (_animationState == 1) {
_animationState = 2;
}
break;
case kAnimationModeWalk:
_animationState = 3;
_animationFrame = 0;
break;
case 4:
if ((unsigned int)(_animationState - 1) > 1) {
_animationState = 0;
_animationFrame = 0;
} else if (_animationState == 1) {
_animationState = 2;
}
break;
case 6:
_animationState = 4;
_animationFrame = 0;
break;
case 7:
_animationState = 3;
_animationFrame = 0;
break;
case 8:
_animationState = 3;
_animationFrame = 0;
break;
case 21:
_animationState = 6;
_animationFrame = 0;
break;
case 43:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 7;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptFreeSlotB::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptFreeSlotB::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptFreeSlotB::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptFreeSlotB::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptFreeSlotB::FledCombat() {
// return false;
}
void AIScriptFreeSlotB::goToRandomUGxx() {
switch (Random_Query(1, 14)) {
case 1:
// kSetUG01
#if BLADERUNNER_ORIGINAL_BUGS
AI_Movement_Track_Append(kActorFreeSlotB, 450, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 451, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 450, 0);
break;
#else
// Don't put rats in UG01 when Lucy is also here
if (!Actor_Query_In_Set(kActorLucy, kSetUG01)) {
AI_Movement_Track_Append(kActorFreeSlotB, 450, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 451, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 450, 0);
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 2:
// kSetUG01
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(466, kSetUG01, 144.98f, -50.13f, -175.75f);
World_Waypoint_Set(547, kSetUG01, 105.6f, -50.13f, -578.46f);
World_Waypoint_Set(548, kSetUG01, 62.0f, -50.13f, -574.0f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 5);
break;
#else
// Don't put rats in UG01 when Lucy is also here
if (!Actor_Query_In_Set(kActorLucy, kSetUG01)) {
World_Waypoint_Set(466, kSetUG01, 144.98f, -50.13f, -175.75f);
World_Waypoint_Set(547, kSetUG01, 105.6f, -50.13f, -578.46f);
World_Waypoint_Set(548, kSetUG01, 62.0f, -50.13f, -574.0f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 5);
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 3:
// kSetUG04
AI_Movement_Track_Append(kActorFreeSlotB, 446, 15);
AI_Movement_Track_Append(kActorFreeSlotB, 447, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 449, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 448, 2);
AI_Movement_Track_Append(kActorFreeSlotB, 449, 0);
break;
case 4:
// kSetUG04
World_Waypoint_Set(466, kSetUG04, -22.70f, 6.39f, 33.12f);
World_Waypoint_Set(547, kSetUG04, -6.70f, -1.74f, -362.88f);
World_Waypoint_Set(548, kSetUG04, 164.0f, 11.87f, -1013.0f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 2);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 0);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 0);
break;
case 5:
// kSetUG05
AI_Movement_Track_Append(kActorFreeSlotB, 457, 15);
AI_Movement_Track_Append(kActorFreeSlotB, 458, 0);
AI_Movement_Track_Append(kActorFreeSlotB, 459, 15);
break;
case 6:
// kSetUG06
AI_Movement_Track_Append(kActorFreeSlotB, 460, 15);
AI_Movement_Track_Append(kActorFreeSlotB, 461, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 460, 15);
break;
case 7:
// kSetUG07 or kSetFreeSlotG
#if BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_In_Set(kActorClovis, kSetUG07)) {
// this check is not very effective since Clovis
// will spawn in the set when McCoy goes to the downwards exit
// at which point a rat may already be in the set and that could
// make them collide with Clovis' path
AI_Movement_Track_Append(kActorFreeSlotB, 39, 10);
} else {
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 1);
// TODO: A bug? the waypoint 548 is created but is unused
}
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 1);
// TODO: A bug? the waypoint 548 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 8:
// kSetUG07
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
// TODO: A bug? the waypoint 548 is created but is unused
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
// TODO: A bug? the waypoint 548 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 9:
// kSetUG07
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 1);
// TODO: A bug? the waypoint 466 is created but is unused
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 1);
// TODO: A bug? the waypoint 466 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 10:
// kSetUG07
#if BLADERUNNER_ORIGINAL_BUGS
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 1);
// TODO: A bug? the waypoint 466 is created but is unused
break;
#else
// Don't put rats in UG07 after the UG18 Guzza scene
// since Clovis may be there too and that does not work well
if (!Game_Flag_Query(kFlagUG18GuzzaScene)) {
World_Waypoint_Set(466, kSetUG07, -88.78f, -12.21f, -184.08f);
World_Waypoint_Set(547, kSetUG07, 250.0f, -12.21f, -342.0f);
World_Waypoint_Set(548, kSetUG07, -164.78f, -12.21f, -832.08f);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 1);
// TODO: A bug? the waypoint 466 is created but is unused
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// fall through
case 11:
// kSetUG09
World_Waypoint_Set(466, kSetUG09, 91.0f, 156.94f, -498.0f);
World_Waypoint_Set(547, kSetUG09, -149.0f, 156.94f, -498.0f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 1);
break;
case 12:
// kSetUG09
World_Waypoint_Set(466, kSetUG09, 91.0f, 156.94f, -498.0f);
World_Waypoint_Set(547, kSetUG09, -149.0f, 156.94f, -498.0f);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 5);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
break;
case 13:
// kSetUG09
#if BLADERUNNER_ORIGINAL_BUGS
// this makes the rat appear on the pipe (top left)
// but this is buggy since it will appear floating there
World_Waypoint_Set(466, kSetUG09, -152.51f, 277.31f, 311.98f);
World_Waypoint_Set(547, kSetUG09, -124.51f, 275.08f, 319.98f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 8);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
#else
// replacing with something more normal
World_Waypoint_Set(466, kSetUG09, -149.0f, 156.94f, -498.0f);
World_Waypoint_Set(547, kSetUG09, -32.60f, 156.94f, -498.0f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 2);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case 14:
// kSetUG12
World_Waypoint_Set(466, kSetUG12, -360.67f, 21.39f, 517.55f);
World_Waypoint_Set(547, kSetUG12, -250.67f, 21.39f, 477.55f);
World_Waypoint_Set(548, kSetUG12, -248.67f, 21.39f, -1454.45f);
AI_Movement_Track_Append(kActorFreeSlotB, 466, 1);
AI_Movement_Track_Append(kActorFreeSlotB, 547, 8);
AI_Movement_Track_Append(kActorFreeSlotB, 548, 1);
break;
default:
// kSetFreeSlotG
AI_Movement_Track_Append(kActorFreeSlotB, 39, Random_Query(1, 10));
break;
}
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,514 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptGaff::AIScriptGaff(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptGaff::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
Actor_Put_In_Set(kActorGaff, kSetFreeSlotC);
Actor_Set_Goal_Number(kActorGaff, kGoalGaffDefault);
//return false;
}
bool AIScriptGaff::Update() {
if ( Global_Variable_Query(kVariableChapter) == 2
&& !Game_Flag_Query(kFlagGaffChapter2Started)
) {
Actor_Set_Goal_Number(kActorGaff, kGoalGaffStartWalkingAround);
Game_Flag_Set(kFlagGaffChapter2Started);
return true;
}
if (Global_Variable_Query(kVariableChapter) == 4
&& Actor_Query_Goal_Number(kActorGaff) < kGoalGaffStartChapter4
) {
Actor_Set_Goal_Number(kActorGaff, kGoalGaffStartChapter4);
}
return false;
}
void AIScriptGaff::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask0) {
AI_Countdown_Timer_Reset(kActorGaff, kActorTimerAIScriptCustomTask0);
Actor_Set_Goal_Number(kActorGaff, kGoalGaffMA07TalkToMcCoy);
}
//return false;
}
void AIScriptGaff::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorGaff) == kGoalGaffMA01ApproachMcCoy) {
Actor_Face_Actor(kActorGaff, kActorMcCoy, true);
Actor_Says(kActorGaff, 0, kAnimationModeTalk);
Loop_Actor_Walk_To_Actor(kActorMcCoy, kActorGaff, 36, false, true);
Actor_Face_Actor(kActorMcCoy, kActorGaff, true);
Actor_Says(kActorMcCoy, 670, kAnimationModeTalk);
Actor_Says(kActorGaff, 10, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 675, kAnimationModeTalk);
if (Game_Flag_Query(kFlagZubenRetired)) {
Actor_Says(kActorGaff, 50, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 695, kAnimationModeTalk);
Actor_Says(kActorGaff, 60, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 700, kAnimationModeTalk);
Actor_Says(kActorGaff, 70, kAnimationModeTalk);
Actor_Clue_Acquire(kActorGaff, kClueMcCoyRetiredZuben, true, -1);
} else {
Actor_Says(kActorGaff, 80, kAnimationModeTalk);
Actor_Says(kActorGaff, 90, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 705, kAnimationModeTalk);
Actor_Says(kActorGaff, 100, kAnimationModeTalk);
Actor_Clue_Acquire(kActorGaff, kClueMcCoyLetZubenEscape, true, -1);
}
Actor_Says(kActorGaff, 20, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 680, kAnimationModeTalk);
Actor_Says(kActorGaff, 30, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 685, kAnimationModeTalk);
Actor_Says(kActorGaff, 40, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 690, kAnimationModeTalk);
Actor_Clue_Acquire(kActorMcCoy, kClueGaffsInformation, true, kActorGaff);
CDB_Set_Crime(kClueZubenSquadPhoto, kCrimeMoonbusHijacking);
Actor_Clue_Acquire(kActorGaff, kClueMcCoyRetiredZuben, true, -1);
Game_Flag_Set(kFlagGaffApproachedMcCoyAboutZuben);
Player_Gains_Control();
Actor_Set_Goal_Number(kActorGaff, kGoalGaffMA01Leave);
}
if (Actor_Query_Goal_Number(kActorGaff) == kGoalGaffCT12GoToSpinner) {
Actor_Set_Goal_Number(kActorGaff, kGoalGaffCT12FlyAway);
}
if (Actor_Query_Goal_Number(kActorGaff) == kGoalGaffStartWalkingAround) {
Actor_Set_Goal_Number(kActorGaff, kGoalGaffWalkAround);
return;// true;
}
if (Actor_Query_Goal_Number(kActorGaff) == kGoalGaffWalkAround) {
Actor_Set_Goal_Number(kActorGaff, kGoalGaffRepeatWalkingAround);
return;// true;
}
if (Actor_Query_Goal_Number(kActorGaff) == kGoalGaffRepeatWalkingAround) {
Actor_Set_Goal_Number(kActorGaff, kGoalGaffWalkAround);
return;// true;
}
// return false;
}
void AIScriptGaff::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGaff::ClickedByPlayer() {
if ((Global_Variable_Query(kVariableChapter) == 2
|| Global_Variable_Query(kVariableChapter) == 3
)
&& Game_Flag_Query(kFlagGaffChapter2Started)
) {
AI_Movement_Track_Pause(kActorGaff);
Actor_Face_Actor(kActorMcCoy, kActorGaff, true);
Actor_Face_Actor(kActorGaff, kActorMcCoy, true);
if (Random_Query(1, 3) == 1) {
Actor_Says(kActorMcCoy, 3970, 14);
Actor_Says(kActorGaff, 100, 13);
} else if (Random_Query(1, 3) == 2) {
Actor_Says(kActorMcCoy, 3970, 14);
Actor_Says(kActorGaff, 110, 13);
} else {
Actor_Says(kActorMcCoy, 3970, 14);
Actor_Says(kActorGaff, 180, 13);
}
AI_Movement_Track_Unpause(kActorGaff);
// return true;
}
// return false;
}
void AIScriptGaff::EnteredSet(int setId) {
// return false;
}
void AIScriptGaff::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptGaff::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptGaff::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// It is impossible to triger this as player has no control at this moment
if (otherActorId == kActorMcCoy
&& combatMode == 1
&& Global_Variable_Query(kVariableChapter) == 4
&& Actor_Query_In_Set(kActorMcCoy, kSetMA07)
&& Actor_Query_Goal_Number(kActorGaff) == kGoalGaffMA07Wait
) {
AI_Countdown_Timer_Reset(kActorGaff, kActorTimerAIScriptCustomTask0);
Actor_Set_Goal_Number(kActorGaff, kGoalGaffMA07ShootMcCoy);
}
// return false;
}
void AIScriptGaff::ShotAtAndMissed() {
// return false;
}
bool AIScriptGaff::ShotAtAndHit() {
return false;
}
void AIScriptGaff::Retired(int byActorId) {
// return false;
}
int AIScriptGaff::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGaff::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalGaffCT12WaitForMcCoy:
Actor_Put_In_Set(kActorGaff, kSetCT01_CT12);
Actor_Set_At_Waypoint(kActorGaff, 43, 0);
return true;
case kGoalGaffCT12GoToSpinner:
AI_Movement_Track_Append(kActorGaff, 123, 1);
AI_Movement_Track_Repeat(kActorGaff);
return true;
case kGoalGaffMA01ApproachMcCoy:
Player_Loses_Control();
AI_Movement_Track_Flush(kActorGaff);
AI_Movement_Track_Append(kActorGaff, 124, 0);
AI_Movement_Track_Append(kActorGaff, 126, 0);
AI_Movement_Track_Repeat(kActorGaff);
return true;
case kGoalGaffMA01Leave:
AI_Movement_Track_Flush(kActorGaff);
AI_Movement_Track_Append(kActorGaff, 124, 0);
AI_Movement_Track_Append(kActorGaff, 35, 0);
AI_Movement_Track_Repeat(kActorGaff);
return true;
case kGoalGaffCT12Leave:
AI_Movement_Track_Flush(kActorGaff);
AI_Movement_Track_Append(kActorGaff, 35, 90);
AI_Movement_Track_Repeat(kActorGaff);
return true;
case kGoalGaffCT12FlyAway:
Game_Flag_Reset(kFlagCT12GaffSpinner);
Scene_Loop_Set_Default(2);
Scene_Loop_Start_Special(kSceneLoopModeOnce, 6, true);
return true;
case kGoalGaffStartWalkingAround:
AI_Movement_Track_Flush(kActorGaff);
AI_Movement_Track_Append(kActorGaff, 35, 300);
AI_Movement_Track_Repeat(kActorGaff);
return true;
case kGoalGaffWalkAround:
{
AI_Movement_Track_Flush(kActorGaff);
AI_Movement_Track_Append(kActorGaff, 82, 1);
AI_Movement_Track_Append(kActorGaff, 76, 1);
AI_Movement_Track_Append(kActorGaff, 78, 1);
int rnd = Random_Query(1, 3);
if (rnd == 1) {
AI_Movement_Track_Append(kActorGaff, 271, 0);
AI_Movement_Track_Append(kActorGaff, 272, 0);
AI_Movement_Track_Append(kActorGaff, 273, 0);
} else if (rnd == 2) {
AI_Movement_Track_Append(kActorGaff, 273, 0);
AI_Movement_Track_Append(kActorGaff, 272, 0);
AI_Movement_Track_Append(kActorGaff, 271, 0);
} else if (rnd == 3) {
AI_Movement_Track_Append(kActorGaff, 272, 0);
AI_Movement_Track_Append(kActorGaff, 273, 0);
}
AI_Movement_Track_Append(kActorGaff, 274, 0);
AI_Movement_Track_Append(kActorGaff, 275, 0);
AI_Movement_Track_Repeat(kActorGaff);
}
return true;
case kGoalGaffRepeatWalkingAround:
AI_Movement_Track_Flush(kActorGaff);
AI_Movement_Track_Append(kActorGaff, 35, 90);
AI_Movement_Track_Repeat(kActorGaff);
return true;
case 299:
AI_Movement_Track_Flush(kActorGaff);
Actor_Put_In_Set(kActorGaff, kSetFreeSlotC);
Actor_Set_At_Waypoint(kActorGaff, 35, 0);
return true;
case kGoalGaffMA07Wait:
Player_Loses_Control();
Actor_Put_In_Set(kActorGaff, kSetMA07);
Actor_Set_At_XYZ(kActorGaff, -102.54f, -172.43f, 463.18f, 1015);
Actor_Set_Goal_Number(kActorGaff, kGoalGaffMA07TalkToMcCoy);
return true;
case kGoalGaffMA07TalkToMcCoy:
Game_Flag_Set(kFlagMA07GaffTalk);
Actor_Face_Actor(kActorGaff, kActorMcCoy, true);
Actor_Says(kActorGaff, 110, 12);
Actor_Face_Actor(kActorMcCoy, kActorGaff, true);
Actor_Says(kActorMcCoy, 2945, 14);
Loop_Actor_Walk_To_Actor(kActorGaff, kActorMcCoy, 180, false, false);
Actor_Says(kActorGaff, 120, 16);
Actor_Says(kActorGaff, 130, 13);
Actor_Says(kActorMcCoy, 2950, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 2955, 16);
Actor_Says_With_Pause(kActorGaff, 140, 1.0f, 14);
Loop_Actor_Walk_To_Actor(kActorMcCoy, kActorGaff, 36, false, false);
Actor_Says(kActorGaff, 150, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 2960, 12);
Actor_Says_With_Pause(kActorGaff, 160, 1.0f, 16);
Actor_Says(kActorMcCoy, 2965, 13);
Actor_Says_With_Pause(kActorGaff, 170, 1.0f, kAnimationModeTalk);
Actor_Says_With_Pause(kActorGaff, 180, 1.0f, 12);
Actor_Says(kActorGaff, 190, 14);
Actor_Says(kActorGaff, 200, 15);
Async_Actor_Walk_To_XYZ(kActorGaff, -388.44f, -162.8f, 165.08f, false, false);
Delay(4000);
Player_Gains_Control();
Actor_Start_Speech_Sample(kActorGaff, 210);
Actor_Set_Goal_Number(kActorGaff, kGoalGaffMA07Left);
return true;
case kGoalGaffMA07Left:
return true;
case kGoalGaffMA07ShootMcCoy:
Actor_Face_Actor(kActorGaff, kActorMcCoy, true);
Actor_Change_Animation_Mode(kActorGaff, kAnimationModeCombatAttack);
Sound_Play(kSfxSMCAL3, 100, 0, 0, 50);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
Actor_Retired_Here(kActorMcCoy, 12, 12, true, -1);
return true;
case kGoalGaffGone:
AI_Movement_Track_Flush(kActorGaff);
Actor_Put_In_Set(kActorGaff, kSetKP05_KP06);
Actor_Set_At_XYZ(kActorGaff, -782.15f, 8.26f, -263.64f, 52);
return true;
}
return false;
}
bool AIScriptGaff::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationGaffIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationGaffWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationGaffCalmPointingWithStickTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case 3:
*animation = kModelAnimationGaffExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGaffCalmPointingWithStickTalk;
}
break;
case 4:
// TODO A bug? This is identical to case 6
*animation = kModelAnimationGaffDescribeTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGaffCalmPointingWithStickTalk;
}
break;
case 5:
// TODO A bug? This is identical to case 7
*animation = kModelAnimationGaffLaughHeadBackTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGaffCalmPointingWithStickTalk;
}
break;
case 6:
*animation = kModelAnimationGaffDescribeTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGaffCalmPointingWithStickTalk;
}
break;
case 7:
*animation = kModelAnimationGaffLaughHeadBackTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGaffCalmPointingWithStickTalk;
}
break;
case 8:
*animation = kModelAnimationGaffEntersSpinner;
++_animationFrame;
// TODO Bug in the game? Why check against McCoy's animation's frameset number of frames?
// kModelAnimationMcCoyEntersSpinner: 25 frames
// kModelAnimationGaffEntersSpinner: 31 frames
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMcCoyEntersSpinner) - 1) {
Actor_Set_Invisible(kActorGaff, true);
*animation = kModelAnimationGaffIdle;
_animationFrame = 0;
// TODO: check this, it was set directly by calling actor script
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeIdle);
Actor_Set_Goal_Number(kActorGaff, kGoalGaffCT12Leave);
}
break;
default:
// Dummy placeholder, kModelAnimationZubenWalking (399) is a Zuben animation
*animation = kModelAnimationZubenWalking;
debugC(6, kDebugAnimation, "AIScriptGaff::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGaff::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_animationFrame = 0;
break;
case kAnimationModeWalk:
if (_animationState != 1) {
_animationState = 1;
_animationFrame = 0;
}
break;
case kAnimationModeTalk:
_animationState = 2;
_animationFrame = 0;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
break;
case 16:
_animationState = 7;
_animationFrame = 0;
break;
case kAnimationModeSpinnerGetIn:
_animationState = 8;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptGaff::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptGaff::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGaff::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGaff::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGaff::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,412 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptGeneralDoll::AIScriptGeneralDoll(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptGeneralDoll::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorGeneralDoll, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorGeneralDoll, 39, 0);
Actor_Set_Goal_Number(kActorGeneralDoll, 100);
}
bool AIScriptGeneralDoll::Update() {
if (Global_Variable_Query(kVariableChapter) == 2
&& Actor_Query_Goal_Number(kActorGeneralDoll) <= 101
&& Player_Query_Current_Scene() == kSceneBB05
) {
Actor_Set_Goal_Number(kActorGeneralDoll, 101);
return true;
}
if (Global_Variable_Query(kVariableChapter) == 3
&& Actor_Query_Goal_Number(kActorGeneralDoll) < 200
) {
return true;
}
return false;
}
void AIScriptGeneralDoll::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2) {
// TODO A BUG? McCoy dies here too (it's in original this way also)
// This is untriggered, so it could be leftover or debug code
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
Actor_Change_Animation_Mode(kActorGeneralDoll, kAnimationModeDie);
AI_Countdown_Timer_Reset(kActorGeneralDoll, kActorTimerAIScriptCustomTask2);
return; //true;
}
return; //false;
}
void AIScriptGeneralDoll::CompletedMovementTrack() {
switch (Actor_Query_Goal_Number(kActorGeneralDoll)) {
case 101:
if (Player_Query_Current_Scene() == kSceneBB05) {
switch (Random_Query(0, 5)) {
case 0:
Ambient_Sounds_Play_Speech_Sound(kActorGeneralDoll, 0, 80, 0, 0, 0);
break;
case 1:
Ambient_Sounds_Play_Speech_Sound(kActorGeneralDoll, 10, 80, 0, 0, 0);
break;
case 2:
Ambient_Sounds_Play_Speech_Sound(kActorGeneralDoll, 20, 80, 0, 0, 0);
break;
case 3:
Ambient_Sounds_Play_Speech_Sound(kActorGeneralDoll, 30, 80, 0, 0, 0);
break;
case 4:
Ambient_Sounds_Play_Speech_Sound(kActorGeneralDoll, 40, 80, 0, 0, 0);
break;
case 5:
Ambient_Sounds_Play_Speech_Sound(kActorGeneralDoll, 50, 80, 0, 0, 0);
break;
}
Actor_Set_Goal_Number(kActorGeneralDoll, 102);
} else {
Actor_Set_Goal_Number(kActorGeneralDoll, 103);
}
return; //true;
case 102:
Actor_Set_Goal_Number(kActorGeneralDoll, 103);
return; //true;
case 103:
Actor_Set_Goal_Number(kActorGeneralDoll, 101);
return; //true;
case 200:
Actor_Set_Goal_Number(kActorGeneralDoll, 201);
return; //true;
case 201:
Actor_Set_Goal_Number(kActorGeneralDoll, 200);
return; //true;
}
return; //false
}
void AIScriptGeneralDoll::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGeneralDoll::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorGeneralDoll, true);
Actor_Voice_Over(30, kActorVoiceOver);
Actor_Voice_Over(40, kActorVoiceOver);
}
void AIScriptGeneralDoll::EnteredSet(int setId) {
// return false;
}
void AIScriptGeneralDoll::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptGeneralDoll::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptGeneralDoll::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptGeneralDoll::ShotAtAndMissed() {
// return false;
}
bool AIScriptGeneralDoll::ShotAtAndHit() {
AI_Movement_Track_Flush(kActorGeneralDoll);
Global_Variable_Increment(kVariableGeneralDollShot, 1);
if (!Game_Flag_Query(kFlagGeneralDollShot)
&& Global_Variable_Query(kVariableGeneralDollShot) == 1
) {
Sound_Play(kSfxSERVOD1, 100, 0, 0, 50);
Game_Flag_Set(kFlagGeneralDollShot);
Actor_Set_Goal_Number(kActorGeneralDoll, 104);
ChangeAnimationMode(kAnimationModeDie);
Actor_Set_Targetable(kActorGeneralDoll, false);
}
return false;
}
void AIScriptGeneralDoll::Retired(int byActorId) {
// return false;
}
int AIScriptGeneralDoll::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGeneralDoll::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 100:
AI_Movement_Track_Flush(kActorGeneralDoll);
AI_Movement_Track_Append(kActorGeneralDoll, 39, 0);
AI_Movement_Track_Repeat(kActorGeneralDoll);
break;
case 101:
AI_Movement_Track_Flush(kActorGeneralDoll);
AI_Movement_Track_Append(kActorGeneralDoll, 196, 0);
AI_Movement_Track_Repeat(kActorGeneralDoll);
break;
case 102:
AI_Movement_Track_Flush(kActorGeneralDoll);
AI_Movement_Track_Append(kActorGeneralDoll, 197, 0);
AI_Movement_Track_Repeat(kActorGeneralDoll);
break;
case 103:
AI_Movement_Track_Flush(kActorGeneralDoll);
if (Random_Query(1, 2) == 1) {
AI_Movement_Track_Append(kActorGeneralDoll, 198, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 329, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 328, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 330, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 331, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 335, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 139, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 138, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 137, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 136, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 135, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 134, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 326, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 327, 0);
} else {
AI_Movement_Track_Append(kActorGeneralDoll, 136, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 137, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 138, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 139, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 335, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 331, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 327, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 326, 0);
}
AI_Movement_Track_Repeat(kActorGeneralDoll);
break;
case 104:
AI_Movement_Track_Flush(kActorGeneralDoll);
break;
case 106:
AI_Movement_Track_Flush(kActorGeneralDoll);
AI_Movement_Track_Append(kActorGeneralDoll, 196, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 197, 0);
AI_Movement_Track_Repeat(kActorGeneralDoll);
break;
case 200:
AI_Movement_Track_Flush(kActorGeneralDoll);
Actor_Put_In_Set(kActorGeneralDoll, kSetBB05);
Actor_Set_At_Waypoint(kActorGeneralDoll, 134, 0);
Actor_Set_Goal_Number(kActorGeneralDoll, 201);
break;
case 201:
AI_Movement_Track_Flush(kActorGeneralDoll);
if (Random_Query(1, 2) == 1) {
AI_Movement_Track_Append(kActorGeneralDoll, 198, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 329, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 328, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 330, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 331, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 335, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 139, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 138, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 137, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 136, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 135, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 134, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 326, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 327, 0);
} else {
AI_Movement_Track_Append(kActorGeneralDoll, 136, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 137, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 138, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 139, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 335, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 331, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 327, 0);
AI_Movement_Track_Append(kActorGeneralDoll, 326, 0);
}
AI_Movement_Track_Repeat(kActorGeneralDoll);
break;
case 299:
AI_Movement_Track_Flush(kActorGeneralDoll);
break;
default:
return false;
}
return true;
}
bool AIScriptGeneralDoll::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelGeneralDollIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelGeneralDollIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelGeneralDollHaltSalute;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelGeneralDollIdle;
_animationFrame = 0;
_animationState = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelGeneralDollHaltSalute)) {
_animationFrame = 0;
}
}
break;
case 2:
*animation = kModelGeneralDollWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelGeneralDollWalking)) {
_animationFrame = 0;
}
break;
case 3:
*animation = kModelGeneralDollGotHit;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelGeneralDollGotHit)) {
*animation = kModelGeneralDollIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 4:
*animation = kModelGeneralDollShotDead;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelGeneralDollShotDead) - 1) {
++_animationFrame;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptGeneralDoll::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGeneralDoll::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState == 1) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = 2;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 1;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 43:
_animationState = 3;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 4;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptGeneralDoll::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptGeneralDoll::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGeneralDoll::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGeneralDoll::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGeneralDoll::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,605 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kGenericWalkerAStates {
kGenericWalkerAStatesIdle = 0,
kGenericWalkerAStatesWalk = 1,
kGenericWalkerAStatesDie = 2,
kGenericWalkerAStatesGun = 3
};
AIScriptGenericWalkerA::AIScriptGenericWalkerA(BladeRunnerEngine *vm) : AIScriptBase(vm) {
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
}
void AIScriptGenericWalkerA::Initialize() {
_animationState = kGenericWalkerAStatesIdle;
_animationFrame = 0;
_animationStateNext = 0;
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
Actor_Set_Goal_Number(kActorGenwalkerA, kGoalGenwalkerDefault);
}
bool AIScriptGenericWalkerA::Update() {
#if !BLADERUNNER_ORIGINAL_BUGS
// extra check for possible fix of Bullet Bob's gun missing
if (Player_Query_Current_Set() == kSetRC04
&& Actor_Query_Goal_Number(kActorGenwalkerA) != kGoalGenwalkerABulletBobsTrackGun
) {
Actor_Set_Goal_Number(kActorGenwalkerA, kGoalGenwalkerABulletBobsTrackGun);
}
#endif // !BLADERUNNER_ORIGINAL_BUGS
switch (Actor_Query_Goal_Number(kActorGenwalkerA)) {
case kGoalGenwalkerDefault:
if (prepareWalker()) {
return true;
}
break;
case kGoalGenwalkerMoving:
if (deltaX != 0.0f || deltaZ != 0.0f) {
movingUpdate();
}
break;
case kGoalGenwalkerABulletBobsTrackGun: // Automatic gun at Bullet Bob
Actor_Face_Actor(kActorGenwalkerA, kActorMcCoy, true);
break;
}
return false;
}
void AIScriptGenericWalkerA::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2) {
AI_Countdown_Timer_Reset(kActorGenwalkerA, kActorTimerAIScriptCustomTask2);
Game_Flag_Reset(kFlagGenericWalkerWaiting);
return;// true;
}
//return false;
}
void AIScriptGenericWalkerA::CompletedMovementTrack() {
#if !BLADERUNNER_ORIGINAL_BUGS
// extra check for possible fix of Bullet Bob's gun missing
if (Player_Query_Current_Set() == kSetRC04
&& Actor_Query_Goal_Number(kActorGenwalkerA) != kGoalGenwalkerABulletBobsTrackGun
) {
Actor_Set_Goal_Number(kActorGenwalkerA, kGoalGenwalkerABulletBobsTrackGun);
return;
}
#endif // !BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_Goal_Number(kActorGenwalkerA) > kGoalGenwalkerDefault) {
Actor_Set_Goal_Number(kActorGenwalkerA, kGoalGenwalkerDefault);
if (!Game_Flag_Query(kFlagGenericWalkerWaiting)) {
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerA, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorGenwalkerA, kActorTimerAIScriptCustomTask2, Random_Query(6, 10));
}
// return true;
}
// return false;
}
void AIScriptGenericWalkerA::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGenericWalkerA::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorGenwalkerA, true);
if (Actor_Query_Goal_Number(kActorGenwalkerA) == kGoalGenwalkerABulletBobsTrackGun) {
Actor_Says(kActorMcCoy, 5290, 18); // kActorGenwalkerA here is actually the tracking gun in Bullet Bob's
} else {
switch (Random_Query(1, 10)) {
case 1:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 2:
Actor_Says(kActorMcCoy, 755, 3);
break;
case 3:
Actor_Says(kActorMcCoy, 940, 3);
break;
case 4:
Actor_Says(kActorMcCoy, 4560, 3);
break;
case 5:
Actor_Says(kActorMcCoy, 4870, 3);
break;
case 6:
Actor_Says(kActorMcCoy, 5125, 3);
break;
case 7:
Actor_Says(kActorMcCoy, 8450, 3);
break;
case 8:
Actor_Says(kActorMcCoy, 1085, 3);
break;
case 9:
Actor_Says(kActorMcCoy, 365, 3); // Re-used line, same as case 1
break;
case 10:
Actor_Says(kActorMcCoy, 7415, 3);
break;
}
}
//return false;
}
void AIScriptGenericWalkerA::EnteredSet(int setId) {
//return false;
}
void AIScriptGenericWalkerA::OtherAgentEnteredThisSet(int otherActorId) {
//return false;
}
void AIScriptGenericWalkerA::OtherAgentExitedThisSet(int otherActorId) {
if (Actor_Query_Goal_Number(kActorGenwalkerA) > kGoalGenwalkerDefault && otherActorId == kActorMcCoy) {
Actor_Set_Goal_Number(kActorGenwalkerA, kGoalGenwalkerDefault);
}
//return false;
}
void AIScriptGenericWalkerA::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
//return false;
}
void AIScriptGenericWalkerA::ShotAtAndMissed() {
//return false;
}
bool AIScriptGenericWalkerA::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorGenwalkerA) > kGoalGenwalkerDefault) {
AI_Movement_Track_Flush(kActorGenwalkerA);
_animationState = kGenericWalkerAStatesDie;
_animationFrame = 0;
Sound_Play(kSfxPOTSPL5, 100, 0, 0, 50);
movingStart();
return true;
}
return false;
}
void AIScriptGenericWalkerA::Retired(int byActorId) {
//return false;
}
int AIScriptGenericWalkerA::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGenericWalkerA::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == kGoalGenwalkerDefault) {
AI_Movement_Track_Flush(kActorGenwalkerA);
Actor_Put_In_Set(kActorGenwalkerA, kSetFreeSlotH);
Global_Variable_Set(kVariableGenericWalkerAModel, -1);
return false;
} else if (newGoalNumber == kGoalGenwalkerMoving) {
return true;
} else if (newGoalNumber == kGoalGenwalkerABulletBobsTrackGun) {
// Bullet Bob's tracking gun
#if !BLADERUNNER_ORIGINAL_BUGS
// Possible bug fix for disappearing gun - don't allow track complete events to interfere with Gun state
AI_Movement_Track_Flush(kActorGenwalkerA);
#endif
Actor_Put_In_Set(kActorGenwalkerA, kSetRC04);
Actor_Set_At_XYZ(kActorGenwalkerA, 0.0, 36.0, -172.0, 491);
Actor_Change_Animation_Mode(kActorGenwalkerA, kAnimationModeCombatIdle);
return true;
}
return false;
}
bool AIScriptGenericWalkerA::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kGenericWalkerAStatesIdle:
switch (Global_Variable_Query(kVariableGenericWalkerAModel)) {
case 0:
*animation = kModelGenWalkerHattedPersonWithUmbrellaStandsStill; // Hatted Person with umbrella still
break;
case 1:
*animation = kModelGenWalkerHoodedPersonWithUmbrellaStandsStill; // Hooded person with umbrella still
break;
case 2:
#if BLADERUNNER_ORIGINAL_BUGS
// Hatted lady with wooden umbrella still (different from 436 model!)
*animation = kModelGenWalkerHattedLadyWithWoodenUmbrellaStandsStill;
#else
// use model 436 and animation frame 4
*animation = kModelGenWalkerHattedPersonWithWoodenUmbrella;
_animationFrame = 4; // frame 4 is used for still
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case 3:
*animation = kModelGenWalkerPunkPersonWithGlassesAndBeardStandsStill; // Person with glasses and beard still
break;
case 4:
*animation = kModelGenWalkerHattedPersonNoUmbrellaStandsStill; // Hatted Person without umbrella still
break;
case 5:
*animation = kModelGenWalkerPunkPersonWithGlassesStandsStill; // Punk person with glasses still
break;
case 6:
*animation = kModelGenWalkerHattedChild; // Hatted child walking
_animationFrame = 11; // frame 11 used for still
break;
case 7:
*animation = kModelGenWalkerChild; // Child walking
_animationFrame = 0; // frame 0 used for still (could also use frame 5)
break;
case 8:
*animation = kModelGenWalkerHattedPersonFastPace; // Hatted person walking fast
_animationFrame = 1; // frame 1 used for still
break;
case 9:
*animation = kModelGenWalkerHattedPersonLoweredFace; // Hatted person walking lowered face
_animationFrame = 6; // frame 6 used for still
break;
}
if (!_vm->_cutContent
|| (Global_Variable_Query(kVariableGenericWalkerAModel) < 6 && Global_Variable_Query(kVariableGenericWalkerAModel) != 2)
) {
_animationFrame = 0;
}
break;
case kGenericWalkerAStatesWalk:
switch (Global_Variable_Query(kVariableGenericWalkerAModel)) {
case 0:
*animation = kModelGenWalkerHattedPersonWithUmbrella; // Hatted person with umbrella walking
break;
case 1:
*animation = kModelGenWalkerHoodedPersonWithUmbrella; // Hooded person with umbrella walking
break;
case 2:
*animation = kModelGenWalkerHattedPersonWithWoodenUmbrella; // Hatted person with wooden umbrella walking
break;
case 3:
*animation = kModelGenWalkerPunkPersonWithGlassesAndBeard; // Person with glasses and beard walking
break;
case 4:
*animation = kModelGenWalkerHattedPersonNoUmbrellaSmallSteps; // Hatted Person without umbrella - walking small steps
break;
case 5:
*animation = kModelGenWalkerPunkPersonWithGlasses; // Punk person with glasses walking
break;
case 6:
*animation = kModelGenWalkerHattedChild; // Hatted child walking
break;
case 7:
*animation = kModelGenWalkerChild; // Child walking
break;
case 8:
*animation = kModelGenWalkerHattedPersonFastPace; // Hatted person walking fast
break;
case 9:
*animation = kModelGenWalkerHattedPersonLoweredFace; // Hatted person walking lowered face
break;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case kGenericWalkerAStatesDie:
// This is an animation for Maggie (exploding) but is also used for generic death states (rats, generic walkers)
// probably for debug purposes
debugC(6, kDebugAnimation, "AIScriptGenericWalkerA::UpdateAnimation() - Current _animationState (%d) is placeholder", _animationState);
*animation = kModelAnimationMaggieExploding;
++_animationFrame;
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieExploding))
{
_animationFrame = 0;
Actor_Set_Goal_Number(kActorGenwalkerA, kGoalGenwalkerDefault);
_animationState = kGenericWalkerAStatesIdle;
deltaX = 0.0f;
deltaZ = 0.0f;
}
break;
case kGenericWalkerAStatesGun:
debugC(6, kDebugAnimation, "AIScriptGenericWalkerA::UpdateAnimation() - Current _animationState (%d) is special (bob's gun)", _animationState);
*animation = kModelAnimationBulletBobsTrackingGun;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationBulletBobsTrackingGun)) {
_animationFrame = 0;
}
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGenericWalkerA::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = kGenericWalkerAStatesIdle;
if (!_vm->_cutContent
|| (Global_Variable_Query(kVariableGenericWalkerAModel) < 6 && Global_Variable_Query(kVariableGenericWalkerAModel) != 2)
) {
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = kGenericWalkerAStatesWalk;
_animationFrame = 0;
break;
case kAnimationModeCombatIdle:
_animationState = kGenericWalkerAStatesGun;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptGenericWalkerA::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptGenericWalkerA::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGenericWalkerA::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGenericWalkerA::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGenericWalkerA::FledCombat() {
//return false;
}
void AIScriptGenericWalkerA::movingStart() {
float mccoyX, mccoyY, mccoyZ;
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorMcCoy, &mccoyX, &mccoyY, &mccoyZ);
Actor_Query_XYZ(kActorGenwalkerA, &walkerX, &walkerY, &walkerZ);
deltaX = walkerX - mccoyX;
deltaZ = walkerZ - mccoyZ;
float dist = sqrt(deltaX * deltaX + deltaZ * deltaZ);
if (dist == 0.0f) {
deltaZ = 0.0f;
deltaX = 0.0f;
} else {
deltaX *= 10.0f / dist;
deltaZ *= 10.0f / dist;
}
}
void AIScriptGenericWalkerA::movingUpdate() {
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorGenwalkerA, &walkerX, &walkerY, &walkerZ);
int facing = Actor_Query_Facing_1024(kActorGenwalkerA);
walkerX += deltaX;
walkerZ += deltaZ;
deltaX = deltaX * 0.97f;
deltaZ = deltaZ * 0.97f;
Actor_Set_At_XYZ(kActorGenwalkerA, walkerX, walkerY, walkerZ, facing);
}
bool AIScriptGenericWalkerA::prepareWalker() {
if (Game_Flag_Query(kFlagGenericWalkerWaiting) || Global_Variable_Query(kVariableGenericWalkerConfig) < 0 || !preparePath()) {
return false;
}
int model = 0;
do {
if (isInside) {
model = Random_Query(3, 5); // 0, 1, 2 models have umbrellas so they should be in outdoors locations
} else {
if (_vm->_cutContent) {
model = Random_Query(0, 9);
} else {
model = Random_Query(0, 5);
}
}
// this while loop ensures choosing a different model for Walker A than the Walker B or Walker C
} while (model == Global_Variable_Query(kVariableGenericWalkerBModel) || model == Global_Variable_Query(kVariableGenericWalkerCModel));
Global_Variable_Set(kVariableGenericWalkerAModel, model);
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerA, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorGenwalkerA, kActorTimerAIScriptCustomTask2, Random_Query(4, 12));
Actor_Set_Goal_Number(kActorGenwalkerA, kGoalGenwalkerMoving);
return true;
}
bool AIScriptGenericWalkerA::preparePath() {
AI_Movement_Track_Flush(kActorGenwalkerA);
int set = Player_Query_Current_Set();
if (set == kSetAR01_AR02) {
isInside = false;
int waypointStart = Random_Query(155, 158);
int waypointEnd = 0;
AI_Movement_Track_Append(kActorGenwalkerA, waypointStart, 0);
do {
waypointEnd = Random_Query(155, 158);
} while (waypointEnd == waypointStart);
if ((waypointStart == 155 || waypointStart == 156) && (waypointEnd == 157 || waypointEnd == 158)) {
AI_Movement_Track_Append(kActorGenwalkerA, 159, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 160, 0);
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerA, 161, Random_Query(15, 30), 904);
}
} else if ((waypointEnd == 155 || waypointEnd == 156) && (waypointStart == 157 || waypointStart == 158)) {
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerA, 161, Random_Query(15, 30), 904);
}
AI_Movement_Track_Append(kActorGenwalkerA, 160, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 159, 0);
} else if ((waypointStart == 155 && waypointEnd == 156) || (waypointStart == 156 && waypointEnd == 155)) {
AI_Movement_Track_Append(kActorGenwalkerA, 159, 0);
}
AI_Movement_Track_Append(kActorGenwalkerA, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerA);
return true;
}
if (set == kSetCT01_CT12) {
isInside = false;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 54, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerA, 56, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 53, 1);
}
AI_Movement_Track_Append(kActorGenwalkerA, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerA);
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 53, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerA, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 54, 1);
}
AI_Movement_Track_Append(kActorGenwalkerA, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerA);
}
return true;
}
if (set == kSetHC01_HC02_HC03_HC04) {
isInside = true;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 164, 0);
// Original code does indeed have duplication of branches here
// TODO This could possible indicate intent of different movement tracks for the actor
// based on repeated "coin flips", but as it was the code block for each branch was identical.
#if 0
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
} else {
#endif
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
//}
} else {
AI_Movement_Track_Append(kActorGenwalkerA, 162, 0);
// Original code matches the if/else blocks here
// Intent seems to be that if the first coin flip fails (0) then a second one is made
// and based on that the actors facing is set or remains unchanged.
// The movement track is the same in both cases.
// Better to preserve the likely effective duplication here
// TODO Check if there's an observable difference between these branches
// and whether kActorGenwalkerB and kActorGenwalkerC need to also have this behaviour.
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 164, 0);
} else {
if (Random_Query(0, 1)) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerA, 166, 0, 30);
}
AI_Movement_Track_Append(kActorGenwalkerA, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 164, 0);
}
}
AI_Movement_Track_Repeat(kActorGenwalkerA);
return true;
}
if (set == kSetRC03) {
isInside = false;
int waypointStart = 0;
int waypointEnd = 0;
do {
waypointStart = Random_Query(167, 171);
} while (waypointStart == 168 || waypointStart == 169);
do {
waypointEnd = Random_Query(167, 171);
} while (waypointEnd == waypointStart || waypointEnd == 168 || waypointEnd == 169);
AI_Movement_Track_Append(kActorGenwalkerA, waypointStart, 0);
if (waypointStart == 170) {
AI_Movement_Track_Append(kActorGenwalkerA, 169, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 168, 0);
} else if (waypointEnd == 170) {
AI_Movement_Track_Append(kActorGenwalkerA, 168, 0);
AI_Movement_Track_Append(kActorGenwalkerA, 169, 0);
}
AI_Movement_Track_Append(kActorGenwalkerA, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerA);
return true;
}
return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,556 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kGenericWalkerBStates {
kGenericWalkerBStatesIdle = 0,
kGenericWalkerBStatesWalk = 1,
kGenericWalkerBStatesDie = 2
};
AIScriptGenericWalkerB::AIScriptGenericWalkerB(BladeRunnerEngine *vm) : AIScriptBase(vm) {
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
}
void AIScriptGenericWalkerB::Initialize() {
_animationState = kGenericWalkerBStatesIdle;
_animationFrame = 0;
_animationStateNext = 0;
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
Actor_Set_Goal_Number(kActorGenwalkerB, kGoalGenwalkerDefault);
}
bool AIScriptGenericWalkerB::Update() {
switch (Actor_Query_Goal_Number(kActorGenwalkerB)) {
case kGoalGenwalkerDefault:
if (prepareWalker()) {
return true;
}
break;
case kGoalGenwalkerMoving:
if (deltaX != 0.0f || deltaZ != 0.0f) {
movingUpdate();
}
break;
}
return false;
}
void AIScriptGenericWalkerB::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2) {
AI_Countdown_Timer_Reset(kActorGenwalkerB, kActorTimerAIScriptCustomTask2);
Game_Flag_Reset(kFlagGenericWalkerWaiting);
return;// true;
}
//return false;
}
void AIScriptGenericWalkerB::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorGenwalkerB) > kGoalGenwalkerDefault) {
Actor_Set_Goal_Number(kActorGenwalkerB, kGoalGenwalkerDefault);
if (!Game_Flag_Query(kFlagGenericWalkerWaiting)) {
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerB, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorGenwalkerB, kActorTimerAIScriptCustomTask2, Random_Query(6, 10));
}
// return true;
}
// return false;
}
void AIScriptGenericWalkerB::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGenericWalkerB::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorGenwalkerB, true);
switch (Random_Query(1, 10)) {
case 1:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 2:
Actor_Says(kActorMcCoy, 755, 3);
break;
case 3:
Actor_Says(kActorMcCoy, 940, 3);
break;
case 4:
Actor_Says(kActorMcCoy, 4560, 3);
break;
case 5:
Actor_Says(kActorMcCoy, 4870, 3);
break;
case 6:
Actor_Says(kActorMcCoy, 5125, 3);
break;
case 7:
Actor_Says(kActorMcCoy, 8450, 3);
break;
case 8:
Actor_Says(kActorMcCoy, 1085, 3);
break;
case 9:
Actor_Says(kActorMcCoy, 365, 3); // Re-used line, same as case 1
break;
case 10:
Actor_Says(kActorMcCoy, 7415, 3);
break;
}
//return false;
}
void AIScriptGenericWalkerB::EnteredSet(int setId) {
//return false;
}
void AIScriptGenericWalkerB::OtherAgentEnteredThisSet(int otherActorId) {
//return false;
}
void AIScriptGenericWalkerB::OtherAgentExitedThisSet(int otherActorId) {
if (Actor_Query_Goal_Number(kActorGenwalkerB) > kGoalGenwalkerDefault && otherActorId == kActorMcCoy) {
Actor_Set_Goal_Number(kActorGenwalkerB, kGoalGenwalkerDefault);
}
//return false;
}
void AIScriptGenericWalkerB::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
//return false;
}
void AIScriptGenericWalkerB::ShotAtAndMissed() {
//return false;
}
bool AIScriptGenericWalkerB::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorGenwalkerB) > kGoalGenwalkerDefault) {
AI_Movement_Track_Flush(kActorGenwalkerB);
_animationState = kGenericWalkerBStatesDie;
_animationFrame = 0;
Sound_Play(kSfxPOTSPL5, 100, 0, 0, 50);
movingStart();
return true;
}
return false;
}
void AIScriptGenericWalkerB::Retired(int byActorId) {
//return false;
}
int AIScriptGenericWalkerB::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGenericWalkerB::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == kGoalGenwalkerDefault) {
AI_Movement_Track_Flush(kActorGenwalkerB);
Actor_Put_In_Set(kActorGenwalkerB, kSetFreeSlotH);
Global_Variable_Set(kVariableGenericWalkerBModel, -1);
return false;
} else if (newGoalNumber == kGoalGenwalkerMoving) {
return true;
}
return false;
}
bool AIScriptGenericWalkerB::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kGenericWalkerBStatesIdle:
switch (Global_Variable_Query(kVariableGenericWalkerBModel)) {
case 0:
*animation = kModelGenWalkerHattedPersonWithUmbrellaStandsStill; // Hatted Person with umbrella still
break;
case 1:
*animation = kModelGenWalkerHoodedPersonWithUmbrellaStandsStill; // Hooded person with umbrella still
break;
case 2:
#if BLADERUNNER_ORIGINAL_BUGS
// Hatted lady with wooden umbrella still (different from 436 model!)
*animation = kModelGenWalkerHattedLadyWithWoodenUmbrellaStandsStill;
#else
// use model 436 and animation frame 4
*animation = kModelGenWalkerHattedPersonWithWoodenUmbrella;
_animationFrame = 4; // frame 4 is used for still
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case 3:
*animation = kModelGenWalkerPunkPersonWithGlassesAndBeardStandsStill;
break;
case 4:
*animation = kModelGenWalkerHattedPersonNoUmbrellaStandsStill;
break;
case 5:
*animation = kModelGenWalkerPunkPersonWithGlassesStandsStill;
break;
case 6:
*animation = kModelGenWalkerHattedChild; // Hatted child walking
_animationFrame = 11; // frame 11 used for still
break;
case 7:
*animation = kModelGenWalkerChild; // Child walking
_animationFrame = 0; // frame 0 used for still (could also use frame 5)
break;
case 8:
*animation = kModelGenWalkerHattedPersonFastPace; // Hatted person walking fast
_animationFrame = 1; // frame 1 used for still
break;
case 9:
*animation = kModelGenWalkerHattedPersonLoweredFace; // Hatted person walking lowered face
_animationFrame = 6; // frame 6 used for still
break;
}
if (!_vm->_cutContent
|| (Global_Variable_Query(kVariableGenericWalkerBModel) < 6 && Global_Variable_Query(kVariableGenericWalkerBModel) != 2)
) {
_animationFrame = 0;
}
break;
case kGenericWalkerBStatesWalk:
switch (Global_Variable_Query(kVariableGenericWalkerBModel)) {
case 0:
*animation = kModelGenWalkerHattedPersonWithUmbrella;
break;
case 1:
*animation = kModelGenWalkerHoodedPersonWithUmbrella;
break;
case 2:
*animation = kModelGenWalkerHattedPersonWithWoodenUmbrella;
break;
case 3:
*animation = kModelGenWalkerPunkPersonWithGlassesAndBeard;
break;
case 4:
*animation = kModelGenWalkerHattedPersonNoUmbrellaSmallSteps;
break;
case 5:
*animation = kModelGenWalkerPunkPersonWithGlasses;
break;
case 6:
*animation = kModelGenWalkerHattedChild; // Hatted child walking
break;
case 7:
*animation = kModelGenWalkerChild; // Child walking
break;
case 8:
*animation = kModelGenWalkerHattedPersonFastPace; // Hatted person walking fast
break;
case 9:
*animation = kModelGenWalkerHattedPersonLoweredFace; // Hatted person walking lowered face
break;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case kGenericWalkerBStatesDie:
// This is an animation for Maggie (exploding) but is also used for generic death states (rats, generic walkers)
// probably for debug purposes
*animation = kModelAnimationMaggieExploding;
++_animationFrame;
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieExploding)) {
_animationFrame = 0;
Actor_Set_Goal_Number(kActorGenwalkerB, kGoalGenwalkerDefault);
_animationState = kGenericWalkerBStatesIdle;
deltaX = 0.0f;
deltaZ = 0.0f;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptGenericWalkerB::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGenericWalkerB::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = kGenericWalkerBStatesIdle;
if (!_vm->_cutContent
|| (Global_Variable_Query(kVariableGenericWalkerBModel) < 6 && Global_Variable_Query(kVariableGenericWalkerBModel) != 2)
) {
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = kGenericWalkerBStatesWalk;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptGenericWalkerB::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptGenericWalkerB::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGenericWalkerB::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGenericWalkerB::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGenericWalkerB::FledCombat() {
//return false;
}
void AIScriptGenericWalkerB::movingStart() {
float mccoyX, mccoyY, mccoyZ;
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorMcCoy, &mccoyX, &mccoyY, &mccoyZ);
Actor_Query_XYZ(kActorGenwalkerB, &walkerX, &walkerY, &walkerZ);
deltaX = walkerX - mccoyX;
deltaZ = walkerZ - mccoyZ;
float dist = sqrt(deltaX * deltaX + deltaZ * deltaZ);
if (dist == 0.0f) {
deltaZ = 0.0f;
deltaX = 0.0f;
} else {
deltaX *= 10.0f / dist;
deltaZ *= 10.0f / dist;
}
}
void AIScriptGenericWalkerB::movingUpdate() {
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorGenwalkerB, &walkerX, &walkerY, &walkerZ);
int facing = Actor_Query_Facing_1024(kActorGenwalkerB);
walkerX += deltaX;
walkerZ += deltaZ;
deltaX = deltaX * 0.97f;
deltaZ = deltaZ * 0.97f;
Actor_Set_At_XYZ(kActorGenwalkerB, walkerX, walkerY, walkerZ, facing);
}
bool AIScriptGenericWalkerB::prepareWalker() {
if (Game_Flag_Query(kFlagGenericWalkerWaiting) || Global_Variable_Query(kVariableGenericWalkerConfig) < 0 || !preparePath()) {
return false;
}
int model = 0;
do {
if (isInside) {
model = Random_Query(3, 5); // 0, 1, 2 models have umbrellas so they should be in outdoors locations
} else {
if (_vm->_cutContent) {
model = Random_Query(0, 9);
} else {
model = Random_Query(0, 5);
}
}
// this while loop ensures choosing a different model for Walker B than the Walker A or Walker C
} while (model == Global_Variable_Query(kVariableGenericWalkerAModel) || model == Global_Variable_Query(kVariableGenericWalkerCModel));
Global_Variable_Set(kVariableGenericWalkerBModel, model);
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerB, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorGenwalkerB, kActorTimerAIScriptCustomTask2, Random_Query(4, 12));
Actor_Set_Goal_Number(kActorGenwalkerB, kGoalGenwalkerMoving);
return true;
}
bool AIScriptGenericWalkerB::preparePath() {
AI_Movement_Track_Flush(kActorGenwalkerB);
int set = Player_Query_Current_Set();
if (set == kSetAR01_AR02) {
isInside = false;
int waypointStart = Random_Query(155, 158);
int waypointEnd = 0;
AI_Movement_Track_Append(kActorGenwalkerB, waypointStart, 0);
do {
waypointEnd = Random_Query(155, 158);
} while (waypointEnd == waypointStart);
if ((waypointStart == 155 || waypointStart == 156) && (waypointEnd == 157 || waypointEnd == 158)) {
AI_Movement_Track_Append(kActorGenwalkerB, 159, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 160, 0);
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerB, 161, Random_Query(15, 30), 904);
}
} else if ((waypointEnd == 155 || waypointEnd == 156) && (waypointStart == 157 || waypointStart == 158)) {
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerB, 161, Random_Query(15, 30), 904);
}
AI_Movement_Track_Append(kActorGenwalkerB, 160, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 159, 0);
} else if ((waypointStart == 155 && waypointEnd == 156) || (waypointStart == 156 && waypointEnd == 155)) {
AI_Movement_Track_Append(kActorGenwalkerB, 159, 0);
}
AI_Movement_Track_Append(kActorGenwalkerB, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerB);
return true;
}
if (set == kSetCT01_CT12) {
isInside = false;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 54, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerB, 56, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 53, 1);
}
AI_Movement_Track_Append(kActorGenwalkerB, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerB);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 53, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerB, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 54, 1);
}
AI_Movement_Track_Append(kActorGenwalkerB, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerB);
}
return true;
}
if (set == kSetHC01_HC02_HC03_HC04) {
isInside = true;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
// Original code does indeed have duplication of branches here
// TODO This could possible indicate intent of different movement tracks for the actor
// based on repeated "coin flips", but as it was the code block for each branch was identical.
#if 0
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
} else {
#endif
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
//}
} else {
AI_Movement_Track_Append(kActorGenwalkerB, 162, 0);
// Original code does indeed have duplication of branches here (similar to above)
// TODO This could possible indicate intent of different movement tracks for the actor
// based on repeated "coin flips", but as it was the code block for each branch was identical.
// NOTE The code for generic walker A here is slightly different, setting based on a "coin flip"
// the actor's "facing".
#if 0
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
} else {
#endif
AI_Movement_Track_Append(kActorGenwalkerB, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 164, 0);
//}
}
AI_Movement_Track_Repeat(kActorGenwalkerB);
return true;
}
if (set == kSetRC03) {
isInside = false;
int waypointStart = 0;
int waypointEnd = 0;
do {
waypointStart = Random_Query(167, 171);
} while (waypointStart == 168 || waypointStart == 169);
do {
waypointEnd = Random_Query(167, 171);
} while (waypointEnd == waypointStart || waypointEnd == 168 || waypointEnd == 169);
AI_Movement_Track_Append(kActorGenwalkerB, waypointStart, 0);
if (waypointStart == 170) {
AI_Movement_Track_Append(kActorGenwalkerB, 169, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 168, 0);
} else if (waypointEnd == 170) {
AI_Movement_Track_Append(kActorGenwalkerB, 168, 0);
AI_Movement_Track_Append(kActorGenwalkerB, 169, 0);
}
AI_Movement_Track_Append(kActorGenwalkerB, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerB);
return true;
}
return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,558 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kGenericWalkerCStates {
kGenericWalkerCStatesIdle = 0,
kGenericWalkerCStatesWalk = 1,
kGenericWalkerCStatesDie = 2
};
AIScriptGenericWalkerC::AIScriptGenericWalkerC(BladeRunnerEngine *vm) : AIScriptBase(vm) {
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
}
void AIScriptGenericWalkerC::Initialize() {
_animationState = kGenericWalkerCStatesIdle;
_animationFrame = 0;
_animationStateNext = 0;
isInside = false;
deltaX = 0.0f;
deltaZ = 0.0f;
Actor_Set_Goal_Number(kActorGenwalkerC, kGoalGenwalkerDefault);
}
bool AIScriptGenericWalkerC::Update() {
switch (Actor_Query_Goal_Number(kActorGenwalkerC)) {
case kGoalGenwalkerDefault:
if (prepareWalker()) {
return true;
}
break;
case kGoalGenwalkerMoving:
if (deltaX != 0.0f || deltaZ != 0.0f) {
movingUpdate();
}
break;
}
return false;
}
void AIScriptGenericWalkerC::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2) {
AI_Countdown_Timer_Reset(kActorGenwalkerC, kActorTimerAIScriptCustomTask2);
Game_Flag_Reset(kFlagGenericWalkerWaiting);
return;// true;
}
//return false;
}
void AIScriptGenericWalkerC::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorGenwalkerC) > kGoalGenwalkerDefault) {
Actor_Set_Goal_Number(kActorGenwalkerC, kGoalGenwalkerDefault);
if (!Game_Flag_Query(kFlagGenericWalkerWaiting)) {
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerC, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorGenwalkerC, kActorTimerAIScriptCustomTask2, Random_Query(6, 10));
}
// return true;
}
// return false;
}
void AIScriptGenericWalkerC::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGenericWalkerC::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorGenwalkerC, true);
switch (Random_Query(1, 10)) {
case 1:
Actor_Says(kActorMcCoy, 365, 3);
break;
case 2:
Actor_Says(kActorMcCoy, 755, 3);
break;
case 3:
Actor_Says(kActorMcCoy, 940, 3);
break;
case 4:
Actor_Says(kActorMcCoy, 4560, 3);
break;
case 5:
Actor_Says(kActorMcCoy, 4870, 3);
break;
case 6:
Actor_Says(kActorMcCoy, 5125, 3);
break;
case 7:
Actor_Says(kActorMcCoy, 8450, 3);
break;
case 8:
Actor_Says(kActorMcCoy, 1085, 3);
break;
case 9:
Actor_Says(kActorMcCoy, 365, 3); // Re-used line, same as case 1
break;
case 10:
Actor_Says(kActorMcCoy, 7415, 3);
break;
}
//return false;
}
void AIScriptGenericWalkerC::EnteredSet(int setId) {
//return false;
}
void AIScriptGenericWalkerC::OtherAgentEnteredThisSet(int otherActorId) {
//return false;
}
void AIScriptGenericWalkerC::OtherAgentExitedThisSet(int otherActorId) {
if (Actor_Query_Goal_Number(kActorGenwalkerC) > kGoalGenwalkerDefault && otherActorId == kActorMcCoy) {
Actor_Set_Goal_Number(kActorGenwalkerC, kGoalGenwalkerDefault);
}
//return false;
}
void AIScriptGenericWalkerC::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
//return false;
}
void AIScriptGenericWalkerC::ShotAtAndMissed() {
//return false;
}
bool AIScriptGenericWalkerC::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorGenwalkerC) > kGoalGenwalkerDefault) {
AI_Movement_Track_Flush(kActorGenwalkerC);
_animationState = kGenericWalkerCStatesDie;
_animationFrame = 0;
Sound_Play(kSfxPOTSPL5, 100, 0, 0, 50);
movingStart();
return true;
}
return false;
}
void AIScriptGenericWalkerC::Retired(int byActorId) {
//return false;
}
int AIScriptGenericWalkerC::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGenericWalkerC::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == kGoalGenwalkerDefault) {
AI_Movement_Track_Flush(kActorGenwalkerC);
Actor_Put_In_Set(kActorGenwalkerC, kSetFreeSlotH);
Global_Variable_Set(kVariableGenericWalkerCModel, -1);
return false;
} else if (newGoalNumber == kGoalGenwalkerMoving) {
return true;
}
return false;
}
bool AIScriptGenericWalkerC::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kGenericWalkerCStatesIdle:
switch (Global_Variable_Query(kVariableGenericWalkerCModel)) {
case 0:
*animation = kModelGenWalkerHattedPersonWithUmbrellaStandsStill; // Hatted Person with umbrella still
break;
case 1:
*animation = kModelGenWalkerHoodedPersonWithUmbrellaStandsStill; // Hooded person with umbrella still
break;
case 2:
#if BLADERUNNER_ORIGINAL_BUGS
// Hatted lady with wooden umbrella still (different from 436 model!)
*animation = kModelGenWalkerHattedLadyWithWoodenUmbrellaStandsStill;
#else
// use model 436 and animation frame 4
*animation = kModelGenWalkerHattedPersonWithWoodenUmbrella;
_animationFrame = 4; // frame 4 is used for still
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case 3:
*animation = kModelGenWalkerPunkPersonWithGlassesAndBeardStandsStill;
break;
case 4:
*animation = kModelGenWalkerHattedPersonNoUmbrellaStandsStill;
break;
case 5:
*animation = kModelGenWalkerPunkPersonWithGlassesStandsStill;
break;
case 6:
*animation = kModelGenWalkerHattedChild; // Hatted child walking
_animationFrame = 11; // frame 11 used for still
break;
case 7:
*animation = kModelGenWalkerChild; // Child walking
_animationFrame = 0; // frame 0 used for still (could also use frame 5)
break;
case 8:
*animation = kModelGenWalkerHattedPersonFastPace; // Hatted person walking fast
_animationFrame = 1; // frame 1 used for still
break;
case 9:
*animation = kModelGenWalkerHattedPersonLoweredFace; // Hatted person walking lowered face
_animationFrame = 6; // frame 6 used for still
break;
}
if (!_vm->_cutContent
|| (Global_Variable_Query(kVariableGenericWalkerCModel) < 6 && Global_Variable_Query(kVariableGenericWalkerCModel) != 2)
) {
_animationFrame = 0;
}
break;
case kGenericWalkerCStatesWalk:
switch (Global_Variable_Query(kVariableGenericWalkerCModel)) {
case 0:
*animation = kModelGenWalkerHattedPersonWithUmbrella;
break;
case 1:
*animation = kModelGenWalkerHoodedPersonWithUmbrella;
break;
case 2:
*animation = kModelGenWalkerHattedPersonWithWoodenUmbrella;
break;
case 3:
*animation = kModelGenWalkerPunkPersonWithGlassesAndBeard;
break;
case 4:
*animation = kModelGenWalkerHattedPersonNoUmbrellaSmallSteps;
break;
case 5:
*animation = kModelGenWalkerPunkPersonWithGlasses;
break;
case 6:
*animation = kModelGenWalkerHattedChild; // Hatted child walking
break;
case 7:
*animation = kModelGenWalkerChild; // Child walking
break;
case 8:
*animation = kModelGenWalkerHattedPersonFastPace; // Hatted person walking fast
break;
case 9:
*animation = kModelGenWalkerHattedPersonLoweredFace; // Hatted person walking lowered face
break;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case kGenericWalkerCStatesDie:
// This is an animation for Maggie (exploding) but is also used for generic death states (rats, generic walkers)
// probably for debug purposes
*animation = kModelAnimationMaggieExploding;
++_animationFrame;
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMaggieExploding))
{
_animationFrame = 0;
Actor_Set_Goal_Number(kActorGenwalkerC, kGoalGenwalkerDefault);
_animationState = kGenericWalkerCStatesIdle;
deltaX = 0.0f;
deltaZ = 0.0f;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptGenericWalkerC::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGenericWalkerC::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = kGenericWalkerCStatesIdle;
if (!_vm->_cutContent
|| (Global_Variable_Query(kVariableGenericWalkerCModel) < 6 && Global_Variable_Query(kVariableGenericWalkerCModel) != 2)
) {
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = kGenericWalkerCStatesWalk;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptGenericWalkerC::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptGenericWalkerC::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGenericWalkerC::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGenericWalkerC::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGenericWalkerC::FledCombat() {
//return false;
}
void AIScriptGenericWalkerC::movingStart() {
float mccoyX, mccoyY, mccoyZ;
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorMcCoy, &mccoyX, &mccoyY, &mccoyZ);
Actor_Query_XYZ(kActorGenwalkerC, &walkerX, &walkerY, &walkerZ);
deltaX = walkerX - mccoyX;
deltaZ = walkerZ - mccoyZ;
float dist = sqrt(deltaX * deltaX + deltaZ * deltaZ);
if (dist == 0.0f) {
deltaZ = 0.0f;
deltaX = 0.0f;
} else {
deltaX *= 10.0f / dist;
deltaZ *= 10.0f / dist;
}
}
void AIScriptGenericWalkerC::movingUpdate() {
float walkerX, walkerY, walkerZ;
Actor_Query_XYZ(kActorGenwalkerC, &walkerX, &walkerY, &walkerZ);
int facing = Actor_Query_Facing_1024(kActorGenwalkerC);
walkerX += deltaX;
walkerZ += deltaZ;
deltaX = deltaX * 0.97f;
deltaZ = deltaZ * 0.97f;
Actor_Set_At_XYZ(kActorGenwalkerC, walkerX, walkerY, walkerZ, facing);
}
bool AIScriptGenericWalkerC::prepareWalker() {
if (Game_Flag_Query(kFlagGenericWalkerWaiting) || Global_Variable_Query(kVariableGenericWalkerConfig) < 2 || !preparePath()) {
return false;
}
int model = 0;
do {
if (isInside) {
model = Random_Query(3, 5); // 0, 1, 2 models have umbrellas so they should be in outdoors locations
} else {
if (_vm->_cutContent) {
model = Random_Query(0, 9);
} else {
model = Random_Query(0, 5);
}
}
// this while loop ensures choosing a different model for Walker C than the Walker A or Walker B
} while (model == Global_Variable_Query(kVariableGenericWalkerAModel) || model == Global_Variable_Query(kVariableGenericWalkerBModel));
Global_Variable_Set(kVariableGenericWalkerCModel, model);
Game_Flag_Set(kFlagGenericWalkerWaiting);
AI_Countdown_Timer_Reset(kActorGenwalkerC, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorGenwalkerC, kActorTimerAIScriptCustomTask2, Random_Query(4, 12));
Actor_Set_Goal_Number(kActorGenwalkerC, kGoalGenwalkerMoving);
return true;
}
bool AIScriptGenericWalkerC::preparePath() {
AI_Movement_Track_Flush(kActorGenwalkerC);
int set = Player_Query_Current_Set();
if (set == kSetAR01_AR02) {
isInside = false;
int waypointStart = Random_Query(155, 158);
int waypointEnd = 0;
AI_Movement_Track_Append(kActorGenwalkerC, waypointStart, 0);
do {
waypointEnd = Random_Query(155, 158);
} while (waypointEnd == waypointStart);
if ((waypointStart == 155 || waypointStart == 156) && (waypointEnd == 157 || waypointEnd == 158)) {
AI_Movement_Track_Append(kActorGenwalkerC, 159, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 160, 0);
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerC, 161, Random_Query(15, 30), 904);
}
} else if ((waypointEnd == 155 || waypointEnd == 156) && (waypointStart == 157 || waypointStart == 158)) {
if (Random_Query(0, 3) == 0) {
AI_Movement_Track_Append_With_Facing(kActorGenwalkerC, 161, Random_Query(15, 30), 904);
}
AI_Movement_Track_Append(kActorGenwalkerC, 160, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 159, 0);
} else if ((waypointStart == 155 && waypointEnd == 156) || (waypointStart == 156 && waypointEnd == 155)) {
AI_Movement_Track_Append(kActorGenwalkerC, 159, 0);
}
AI_Movement_Track_Append(kActorGenwalkerC, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerC);
return true;
}
if (set == kSetCT01_CT12) {
isInside = false;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 54, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerC, 56, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 53, 1);
}
AI_Movement_Track_Append(kActorGenwalkerC, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerC);
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 53, 1);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append(kActorGenwalkerC, 43, 1);
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 54, 1);
}
AI_Movement_Track_Append(kActorGenwalkerC, 40, 1);
AI_Movement_Track_Repeat(kActorGenwalkerC);
}
return true;
}
if (set == kSetHC01_HC02_HC03_HC04) {
isInside = true;
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 164, 0);
// Original code does indeed have duplication of branches here
// TODO This could possible indicate intent of different movement tracks for the actor
// based on repeated "coin flips", but as it was the code block for each branch was identical.
#if 0
if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
} else {
#endif
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
//}
} else {
AI_Movement_Track_Append(kActorGenwalkerC, 162, 0);
// Original code does indeed have duplication of branches here (similar to above)
// TODO This could possible indicate intent of different movement tracks for the actor
// based on repeated "coin flips", but as it was the code block for each branch was identical.
// NOTE The code for generic walker A here is slightly different, setting based on a "coin flip"
// the actor's "facing".
if (Random_Query(0, 1)) {
#if 0
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 164, 0);
} else if (Random_Query(0, 1)) {
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 164, 0);
} else {
#endif
AI_Movement_Track_Append(kActorGenwalkerC, 163, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 164, 0);
}
}
AI_Movement_Track_Repeat(kActorGenwalkerC);
return true;
}
if (set == kSetRC03) {
isInside = false;
int waypointStart = 0;
int waypointEnd = 0;
do {
waypointStart = Random_Query(167, 171);
} while (waypointStart == 168 || waypointStart == 169);
do {
waypointEnd = Random_Query(167, 171);
} while (waypointEnd == waypointStart || waypointEnd == 168 || waypointEnd == 169);
AI_Movement_Track_Append(kActorGenwalkerC, waypointStart, 0);
if (waypointStart == 170) {
AI_Movement_Track_Append(kActorGenwalkerC, 169, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 168, 0);
} else if (waypointEnd == 170) {
AI_Movement_Track_Append(kActorGenwalkerC, 168, 0);
AI_Movement_Track_Append(kActorGenwalkerC, 169, 0);
}
AI_Movement_Track_Append(kActorGenwalkerC, waypointEnd, 0);
AI_Movement_Track_Repeat(kActorGenwalkerC);
return true;
}
return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptGovernorKolvig::AIScriptGovernorKolvig(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptGovernorKolvig::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptGovernorKolvig::Update() {
return false;
}
void AIScriptGovernorKolvig::TimerExpired(int timer) {
//return false;
}
void AIScriptGovernorKolvig::CompletedMovementTrack() {
//return false;
}
void AIScriptGovernorKolvig::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGovernorKolvig::ClickedByPlayer() {
//return false;
}
void AIScriptGovernorKolvig::EnteredSet(int setId) {
// return false;
}
void AIScriptGovernorKolvig::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptGovernorKolvig::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptGovernorKolvig::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptGovernorKolvig::ShotAtAndMissed() {
// return false;
}
bool AIScriptGovernorKolvig::ShotAtAndHit() {
return false;
}
void AIScriptGovernorKolvig::Retired(int byActorId) {
// return false;
}
int AIScriptGovernorKolvig::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGovernorKolvig::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptGovernorKolvig::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptGovernorKolvig::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptGovernorKolvig::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGovernorKolvig::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGovernorKolvig::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGovernorKolvig::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,305 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptGrigorian::AIScriptGrigorian(BladeRunnerEngine *vm) : AIScriptBase(vm) {
// _varChooseIdleAnimation can have valid values: 0, 1, 2
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
}
void AIScriptGrigorian::Initialize() {
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
_animationStateNext = 0;
_animationFrame = 0;
_animationState = 0;
}
bool AIScriptGrigorian::Update() {
if ( Actor_Query_Friendliness_To_Other(kActorGrigorian, kActorMcCoy) < 30
&& !Game_Flag_Query(kFlagGrigorianDislikeMcCoy)
) {
Game_Flag_Set(kFlagGrigorianDislikeMcCoy);
return true;
}
return false;
}
void AIScriptGrigorian::TimerExpired(int timer) {
//return false;
}
void AIScriptGrigorian::CompletedMovementTrack() {
//return false;
}
void AIScriptGrigorian::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptGrigorian::ClickedByPlayer() {
//return false;
}
void AIScriptGrigorian::EnteredSet(int setId) {
// return false;
}
void AIScriptGrigorian::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptGrigorian::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptGrigorian::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptGrigorian::ShotAtAndMissed() {
// return false;
}
bool AIScriptGrigorian::ShotAtAndHit() {
return false;
}
void AIScriptGrigorian::Retired(int byActorId) {
// return false;
}
int AIScriptGrigorian::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptGrigorian::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptGrigorian::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationGrigorianStandIdle;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
++_animationFrame;
if (_animationFrame == 5 || _animationFrame == 13) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(2, 4);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandIdle)) {
_animationFrame = 0;
_varChooseIdleAnimation = Random_Query(0, 2);
}
}
} else if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationGrigorianStandAnnoyedTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandAnnoyedTalk)) {
*animation = kModelAnimationGrigorianStandIdle;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
} else if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationGrigorianStandArmsCrossedTalk;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
++_animationFrame;
if (_animationFrame >= 8 && _animationFrame <= 10) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(2, 4);
}
#if BLADERUNNER_ORIGINAL_BUGS
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandIdle)) {
*animation = kModelAnimationGrigorianStandIdle;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
#else
// bugfix set proper current animation here to get frameset number of frames
// (could also use *animation)
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandArmsCrossedTalk)) {
*animation = kModelAnimationGrigorianStandIdle;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
}
}
break;
case 1:
*animation = kModelAnimationGrigorianStandAnnoyedTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandAnnoyedTalk)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationGrigorianStandProtestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandProtestTalk)) {
_animationFrame = 0;
}
break;
case 3:
*animation = kModelAnimationGrigorianStandProtestMoreTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandProtestMoreTalk)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGrigorianStandProtestTalk;
}
break;
case 4:
*animation = kModelAnimationGrigorianStandProtestEvenMoreTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandProtestEvenMoreTalk)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGrigorianStandProtestTalk;
}
break;
case 5:
*animation = kModelAnimationGrigorianStandInsistentTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandInsistentTalk)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGrigorianStandProtestTalk;
}
break;
case 6:
*animation = kModelAnimationGrigorianStandDismissOrAccuseTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandDismissOrAccuseTalk)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGrigorianStandProtestTalk;
}
break;
case 7:
*animation = kModelAnimationGrigorianStandBegOrMockingTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationGrigorianStandBegOrMockingTalk)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationGrigorianStandProtestTalk;
}
break;
default:
// Dummy placeholder, kModelAnimationZubenWalking (399) is a Zuben animation
*animation = kModelAnimationZubenWalking;
debugC(6, kDebugAnimation, "AIScriptGrigorian::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptGrigorian::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_animationFrame = 0;
break;
case kAnimationModeWalk:
// TODO A bug? This animation state is not for walking. It is for kModelAnimationGrigorianStandAnnoyedTalk.
if (_animationState != 1) {
_animationState = 1;
_animationFrame = 0;
}
break;
case kAnimationModeTalk:
_animationState = 2;
_animationFrame = 0;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
break;
case 16:
_animationState = 7;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptGrigorian::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptGrigorian::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptGrigorian::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptGrigorian::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptGrigorian::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,806 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHanoi::AIScriptHanoi(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
// _varChooseIdleAnimation can have valid values: 0, 1
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
_var4 = 1;
}
void AIScriptHanoi::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
_var4 = 1;
Actor_Set_Goal_Number(kActorHanoi, 0);
}
bool AIScriptHanoi::Update() {
if (Actor_Query_Goal_Number(kActorHolloway) == kGoalHollowayGoToNR07) {
AI_Countdown_Timer_Reset(kActorHanoi, kActorTimerAIScriptCustomTask0);
}
if (Global_Variable_Query(kVariableChapter) == 3
&& Actor_Query_Goal_Number(kActorHanoi) < kGoalHanoiDefault
) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDefaultPosition);
}
if (Player_Query_Current_Scene() != kSceneNR03
&& Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR08Left
) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDefaultPosition);
}
if (Player_Query_Current_Scene() == kSceneNR03
&& Actor_Query_Goal_Number(kActorHanoi) != kGoalHanoiNR03StartGuarding
&& Actor_Query_Goal_Number(kActorHanoi) != kGoalHanoiNR08WatchShow
&& Actor_Query_Goal_Number(kActorHanoi) != kGoalHanoiNR08Leave
&& Actor_Query_Goal_Number(kActorHanoi) != kGoalHanoiNR08Left
) {
// McCoy close to table swivel
if (Actor_Query_Inch_Distance_From_Waypoint(kActorMcCoy, 364) < 420) {
if (Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR03GoToDefaultPosition) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToSwivelTable);
}
} else if (Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR03GoToSwivelTable) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDefaultPosition);
}
// McCoy close to office door
if (Actor_Query_Inch_Distance_From_Waypoint(kActorMcCoy, 361) < 240) {
if (Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR03GoToDefaultPosition) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToOfficeDoor);
}
} else if (Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR03GoToOfficeDoor) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDefaultPosition);
}
// McCoy close to dancer
if (Actor_Query_Inch_Distance_From_Actor(kActorMcCoy, kActorHysteriaPatron1) < 120
&& Actor_Query_Which_Set_In(kActorHanoi) == kSetNR03
&& Actor_Query_Goal_Number(kActorHanoi) != kGoalHanoiNR03GoToDancer
) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDancer);
}
}
return false;
}
void AIScriptHanoi::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask0) {
if (Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR03StartGuarding) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDefaultPosition);
return; //true;
}
if (Actor_Query_Goal_Number(kActorHanoi) != kGoalHanoiThrowOutMcCoy) {
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR07TalkToMcCoy);
return; //true;
}
}
return; //false;
}
void AIScriptHanoi::CompletedMovementTrack() {
switch (Actor_Query_Goal_Number(kActorHanoi)) {
case kGoalHanoiNR07TalkToMcCoy:
Actor_Says(kActorHanoi, 130, 3);
Actor_Says(kActorDektora, 540, 30);
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR07GrabMcCoy);
break;
case kGoalHanoiNR07GrabMcCoy:
Actor_Face_Actor(kActorHanoi, kActorMcCoy, true);
Actor_Face_Actor(kActorMcCoy, kActorHanoi, true);
Actor_Change_Animation_Mode(kActorHanoi, 23);
Actor_Set_Invisible(kActorMcCoy, true);
Actor_Says(kActorMcCoy, 3595, kAnimationModeTalk);
Actor_Says(kActorHanoi, 140, kAnimationModeTalk);
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiThrowOutMcCoy);
break;
case kGoalHanoiNR03GoToDancer:
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDefaultPosition);
break;
case kGoalHanoiNR08Leave:
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR08Left);
break;
case kGoalHanoiNR04Enter:
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR04ShootMcCoy);
break;
default:
return; //false;
}
return; //true;
}
void AIScriptHanoi::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHanoi::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR08WatchShow
|| Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR08Leave
) {
Actor_Face_Actor(kActorMcCoy, kActorHanoi, true);
Actor_Says(kActorMcCoy, 8915, 11);
if (Actor_Query_Goal_Number(kActorHanoi) == kGoalHanoiNR08WatchShow) {
Actor_Says(kActorHanoi, 210, kAnimationModeTalk);
}
}
}
void AIScriptHanoi::EnteredSet(int setId) {
// return false;
}
void AIScriptHanoi::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHanoi::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHanoi::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (Player_Query_Current_Scene() == kSceneNR03
&& otherActorId == kActorMcCoy
&& combatMode
) {
Player_Set_Combat_Mode(false);
#if BLADERUNNER_ORIGINAL_BUGS
// redundant call to lose control here
Player_Loses_Control();
#endif
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiThrowOutMcCoy);
return; //true;
}
return; //false;
}
void AIScriptHanoi::ShotAtAndMissed() {
// return false;
}
bool AIScriptHanoi::ShotAtAndHit() {
return false;
}
void AIScriptHanoi::Retired(int byActorId) {
// return false;
}
int AIScriptHanoi::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHanoi::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 0) {
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append(kActorHanoi, 39, 0);
AI_Movement_Track_Repeat(kActorHanoi);
return true;
}
switch (newGoalNumber) {
case kGoalHanoiDefault:
AI_Countdown_Timer_Start(kActorHanoi, kActorTimerAIScriptCustomTask0, 45);
break;
case kGoalHanoiResetTimer:
AI_Countdown_Timer_Reset(kActorHanoi, kActorTimerAIScriptCustomTask0);
break;
case kGoalHanoiNR07TalkToMcCoy:
if (Actor_Query_Which_Set_In(kActorMcCoy) == kSetNR07
&& Actor_Query_In_Set(kActorDektora, kSetNR07)
) {
Player_Loses_Control();
Actor_Put_In_Set(kActorHanoi, kSetNR07);
Actor_Set_At_XYZ(kActorHanoi, -102.0f, -73.5f, -233.0f, 0);
Async_Actor_Walk_To_Waypoint(kActorMcCoy, 338, 0, false);
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append(kActorHanoi, 336, 1);
AI_Movement_Track_Repeat(kActorHanoi);
} else {
Actor_Set_Goal_Number(kActorHanoi, 0);
}
break;
case kGoalHanoiNR07GrabMcCoy:
if (Actor_Query_Which_Set_In(kActorMcCoy) != kSetNR07) {
return false;
}
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append(kActorHanoi, 337, 0);
AI_Movement_Track_Repeat(kActorHanoi);
break;
case 204:
Actor_Says(kActorHanoi, 210, kAnimationModeTalk);
Actor_Change_Animation_Mode(kActorHanoi, 23);
break;
case kGoalHanoiNR03GoToDefaultPosition:
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append_With_Facing(kActorHanoi, 362, 0, 300);
AI_Movement_Track_Repeat(kActorHanoi);
break;
case kGoalHanoiNR03GoToSwivelTable:
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append_With_Facing(kActorHanoi, 363, 0, 500);
AI_Movement_Track_Repeat(kActorHanoi);
break;
case kGoalHanoiNR03GoToOfficeDoor:
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append_With_Facing(kActorHanoi, 361, 0, 457);
AI_Movement_Track_Repeat(kActorHanoi);
break;
case kGoalHanoiNR03GoToDancer:
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append_With_Facing(kActorHanoi, 365, Random_Query(15, 20), 600);
AI_Movement_Track_Repeat(kActorHanoi);
break;
case kGoalHanoiNR03StartGuarding:
Actor_Put_In_Set(kActorHanoi, kSetNR03);
Actor_Set_At_Waypoint(kActorHanoi, 362, 300);
AI_Countdown_Timer_Reset(kActorHanoi, kActorTimerAIScriptCustomTask0);
AI_Countdown_Timer_Start(kActorHanoi, kActorTimerAIScriptCustomTask0, 6);
break;
case kGoalHanoiThrowOutMcCoy:
Game_Flag_Set(kFlagNR03McCoyThrownOut);
AI_Countdown_Timer_Reset(kActorHanoi, kActorTimerAIScriptCustomTask0);
#if BLADERUNNER_ORIGINAL_BUGS
Player_Loses_Control();
#else
// Lose control only if not already lost control (like in the case of Dektora's dressing room NR07 time-out)
if (Player_Has_Control()) {
Player_Loses_Control();
}
#endif
Player_Set_Combat_Mode(false); // this is missing in ITA and ESP versions of the game
Actor_Force_Stop_Walking(kActorMcCoy);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
Actor_Set_Invisible(kActorMcCoy, true);
AI_Movement_Track_Flush(kActorHanoi);
Actor_Put_In_Set(kActorHanoi, kSetNR01);
Actor_Set_At_XYZ(kActorHanoi, -444.0f, 24.0f, -845.0f, 512);
Actor_Change_Animation_Mode(kActorHanoi, 78);
Set_Enter(kSetNR01, kSceneNR01);
break;
case kGoalHanoiNR08WatchShow:
AI_Movement_Track_Flush(kActorHanoi);
Actor_Put_In_Set(kActorHanoi, kSetNR05_NR08);
Actor_Set_At_XYZ(kActorHanoi, -1387.51f, 0.32f, 288.16f, 292);
break;
case kGoalHanoiNR08Leave:
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append(kActorHanoi, 439, 0);
AI_Movement_Track_Append(kActorHanoi, 39, 45);
AI_Movement_Track_Repeat(kActorHanoi);
break;
case kGoalHanoiNR08Left:
break;
case kGoalHanoiNR04Enter:
Actor_Put_In_Set(kActorHanoi, kSetNR04);
Actor_Set_At_XYZ(kActorHanoi, -47.0f, 0.0f, 334.0f, 535);
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append(kActorHanoi, 549, 0);
AI_Movement_Track_Repeat(kActorHanoi);
break;
case kGoalHanoiNR04ShootMcCoy:
Actor_Face_Actor(kActorHanoi, kActorMcCoy, true);
Actor_Change_Animation_Mode(kActorHanoi, kAnimationModeCombatAttack);
Actor_Retired_Here(kActorMcCoy, 12, 12, true, -1);
break;
case 9999:
AI_Movement_Track_Flush(kActorHanoi);
break;
default:
return false;
}
return true;
}
bool AIScriptHanoi::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation > 0) {
*animation = kModelAnimationHanoiScratchesBackIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelAnimationHanoiLooksAroundIdle;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
break;
}
*animation = kModelAnimationHanoiLooksAroundIdle;
if (_varNumOfTimesToHoldCurrentFrame != 0) {
--_varNumOfTimesToHoldCurrentFrame;
if (!Random_Query(0, 6)) {
_var4 = -_var4;
}
} else {
_animationFrame += _var4;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(*animation) - 1;
}
if (_animationFrame == 5
|| _animationFrame == 15
|| _animationFrame == 11
|| _animationFrame == 0
) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(5, 12);
}
if (_animationFrame >= 10
&& _animationFrame <= 13
) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 1);
}
if (_animationFrame == 0) {
if (!Random_Query(0, 4)) {
_varChooseIdleAnimation = 1;
}
}
}
break;
case 1:
if (_varChooseIdleAnimation > 0) {
*animation = kModelAnimationHanoiScratchesBackIdle;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(*animation) / 2) {
_animationFrame += 2;
} else {
_animationFrame -= 2;
}
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(*animation) - 1
|| _animationFrame <= 0
) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
} else {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
break;
case 2:
*animation = kModelAnimationHanoiGrabsMcCoy;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 3;
*animation = kModelAnimationHanoiHoldsMcCoyUp;
}
break;
case 3:
*animation = kModelAnimationHanoiHoldsMcCoyUp;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case 4:
*animation = kModelAnimationHanoiHoldsMcCoyUpAndTalks;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 3;
*animation = kModelAnimationHanoiHoldsMcCoyUp;
}
break;
case 5:
*animation = kModelAnimationHanoiGrabsMcCoy;
--_animationFrame;
if (_animationFrame == 0) {
_animationState = 0;
_animationFrame = 0;
*animation = kModelAnimationHanoiLooksAroundIdle;
Actor_Face_Actor(kActorMcCoy, kActorHanoi, true);
Actor_Set_Invisible(kActorMcCoy, false);
if (Actor_Query_In_Set(kActorHanoi, kSetNR01)) {
AI_Movement_Track_Flush(kActorHanoi);
AI_Movement_Track_Append(kActorHanoi, 350, 0);
AI_Movement_Track_Append(kActorHanoi, 39, 0);
AI_Movement_Track_Repeat(kActorHanoi);
}
}
break;
case 6:
*animation = kModelAnimationSadikPicksUpAndThrowsMcCoy; // Sadik is used in this animation, but he is well hidden
++_animationFrame;
if (_animationFrame > 26) {
Actor_Change_Animation_Mode(kActorHanoi, kAnimationModeIdle);
_animationState = 0;
_animationFrame = 0;
*animation = kModelAnimationHanoiLooksAroundIdle;
Actor_Set_Goal_Number(kActorMcCoy, kGoalMcCoyNR01ThrownOut);
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR03GoToDefaultPosition);
}
break;
case 7:
*animation = kModelAnimationHanoiWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case 8:
*animation = kModelAnimationHanoiCombatIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case 9:
*animation = kModelAnimationHanoiCombatKicksDoorIn;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
Actor_Change_Animation_Mode(kActorHanoi, kAnimationModeCombatIdle);
_animationState = 8;
_animationFrame = 0;
*animation = kModelAnimationHanoiCombatIdle;
Actor_Set_Goal_Number(kActorHanoi, kGoalHanoiNR04ShootMcCoy);
}
break;
case 10:
*animation = kModelAnimationHanoiCombatFiresGun;
++_animationFrame;
if (_animationFrame == 4) {
Ambient_Sounds_Play_Sound(kSfxSHOTCOK1, 77, 0, 0, 20);
}
if (_animationFrame == 6) {
Ambient_Sounds_Play_Sound(kSfxSHOTGUN1, 97, 0, 0, 20);
}
if (_animationFrame == 5) {
Actor_Force_Stop_Walking(kActorMcCoy);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
Actor_Change_Animation_Mode(kActorHanoi, kAnimationModeCombatIdle);
_animationFrame = 0;
_animationState = 8;
*animation = kModelAnimationHanoiCombatIdle;
}
break;
case 11:
*animation = kModelAnimationHanoiPunchUpAttack;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelAnimationHanoiLooksAroundIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 12:
*animation = kModelAnimationHanoiGotHitOrViolentHeadNod;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelAnimationHanoiCombatIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 13:
*animation = kModelAnimationHanoiShotDead;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(*animation) - 1) {
++_animationFrame;
}
break;
case 14:
*animation = kModelAnimationHanoiCalmTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
// _resumeIdleAfterFramesetCompletesFlag is never set so it's always false, thus this does not evaluate true
_animationState = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
}
break;
case 15:
*animation = kModelAnimationHanoiExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 14;
*animation = kModelAnimationHanoiCalmTalk;
}
break;
case 16:
*animation = kModelAnimationHanoiDownwardsNodTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 14;
*animation = kModelAnimationHanoiCalmTalk;
}
break;
case 17:
*animation = kModelAnimationHanoiDenyTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 14;
*animation = kModelAnimationHanoiCalmTalk;
}
break;
case 18:
*animation = kModelAnimationHanoiSlightBowingTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 14;
*animation = kModelAnimationHanoiCalmTalk;
}
break;
case 19:
*animation = kModelAnimationHanoiLaughTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 14;
*animation = kModelAnimationHanoiCalmTalk;
}
break;
case 20:
*animation = kModelAnimationHanoiMockTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 14;
*animation = kModelAnimationHanoiCalmTalk;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptHanoi::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptHanoi::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState == 2
|| _animationState == 3
) {
_animationState = 3;
} else {
_animationState = 0;
}
_animationFrame = 0;
break;
case kAnimationModeWalk:
_animationState = 7;
_animationFrame = 0;
break;
case kAnimationModeTalk:
if (_animationState == 3) {
_animationState = 4;
_animationFrame = 0;
} else {
_animationStateNext = 14;
_animationNext = kModelAnimationHanoiCalmTalk;
_animationState = 1;
}
break;
case kAnimationModeCombatIdle:
_animationState = 8;
_animationFrame = 0;
break;
case kAnimationModeCombatAttack:
_animationState = 10;
_animationFrame = 0;
break;
case 12:
_animationStateNext = 15;
_animationNext = kModelAnimationHanoiExplainTalk;
_animationState = 1;
break;
case 13:
_animationStateNext = 16;
_animationNext = kModelAnimationHanoiDownwardsNodTalk;
_animationState = 1;
break;
case 14:
_animationStateNext = 17;
_animationNext = kModelAnimationHanoiDenyTalk;
_animationState = 1;
break;
case 15:
_animationStateNext = 18;
_animationNext = kModelAnimationHanoiSlightBowingTalk;
_animationState = 1;
break;
case 16:
// Used when Hanoi says "You're real cute" to McCoy (in NR03),
// when McCoy first tries to sit on the rotating couch
#if BLADERUNNER_ORIGINAL_BUGS
// TODO a bug? uses kModelAnimationHanoiSlightBowingTalk (654) again like case 15
_animationStateNext = 18;
_animationNext = kModelAnimationHanoiSlightBowingTalk;
#else
_animationStateNext = 19;
_animationNext = kModelAnimationHanoiLaughTalk;
#endif
_animationState = 1;
break;
case 17:
_animationStateNext = 20;
_animationNext = kModelAnimationHanoiMockTalk;
_animationState = 1;
break;
case kAnimationModeHit:
// fall through
case kAnimationModeCombatHit:
_animationState = 12;
_animationFrame = 0;
break;
case 23:
if (_animationState != 3
&& _animationState != 4
) {
Actor_Set_Invisible(kActorMcCoy, true);
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 5;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationHanoiGrabsMcCoy) - 1;
}
break;
case kAnimationModeDie:
_animationState = 13;
_animationFrame = 0;
break;
case 71:
_animationState = 9;
_animationFrame = 0;
break;
case 78:
_animationState = 6;
_animationFrame = 16;
break;
default:
debugC(6, kDebugAnimation, "AIScriptHanoi::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptHanoi::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHanoi::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHanoi::ReachedMovementTrackWaypoint(int waypointId) {
if (waypointId == 365) {
Actor_Face_Actor(kActorHanoi, kActorHysteriaPatron1, true);
}
return true;
}
void AIScriptHanoi::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,424 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHasan::AIScriptHasan(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_var1 = 6;
_var2 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
_var4 = 0;
_var5 = 0;
// _varChooseIdleAnimation can have valid values: 0, 1, 2
_varChooseIdleAnimation = 0;
}
void AIScriptHasan::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_var1 = 6;
_var2 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
_var4 = 0;
_var5 = 0;
_varChooseIdleAnimation = 0;
Actor_Put_In_Set(kActorHasan, kSetAR01_AR02);
Actor_Set_At_XYZ(kActorHasan, -214.0f, 0.0f, -1379.0f, 371);
Actor_Set_Goal_Number(kActorHasan, kGoalHasanDefault);
}
bool AIScriptHasan::Update() {
if (_vm->_cutContent) {
if (Global_Variable_Query(kVariableChapter) == 1
&& Actor_Query_Goal_Number(kActorHasan) != kGoalHasanIsAway)
{
// use this goal to put Hasan in a FreeSlot set for Act 1
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsAway);
return true;
} else if (Global_Variable_Query(kVariableChapter) == 2
&& Actor_Query_Goal_Number(kActorHasan) != kGoalHasanDefault
) {
Actor_Set_Goal_Number(kActorHasan, kGoalHasanDefault);
return true;
} else if (Global_Variable_Query(kVariableChapter) > 2
&& Actor_Query_Goal_Number(kActorHasan) < kGoalHasanIsWalkingAroundIsAtAR02) {
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsWalkingAroundIsAtAR02);
return true;
}
return false;
} else {
// original behavior results in Hasan going away when chapter 3 begins
if (Global_Variable_Query(kVariableChapter) != 3 || Actor_Query_Goal_Number(kActorHasan) >= kGoalHasanIsAway)
return false;
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsAway);
return true;
}
}
void AIScriptHasan::TimerExpired(int timer) {
//return false;
}
void AIScriptHasan::CompletedMovementTrack() {
if (_vm->_cutContent) {
//
// *after Act 2* Hasan will be leaving Animoid Row for sometime
if (Global_Variable_Query(kVariableChapter) > 2) {
int maxHasanLeaveProb = 4;
// if Bullet Bob is dead or McCoy reprimanded Bob about Hasan,
// then Hasan is less likely to leave at Animoid Row, *after Act 2*
if (Game_Flag_Query(kFlagMcCoyTalkedToBulletBobAboutHasan)
|| Actor_Query_Goal_Number(kGoalBulletBobDead)
|| Actor_Query_Goal_Number(kGoalBulletBobGone)
) {
maxHasanLeaveProb = 10;
}
if (Actor_Query_Goal_Number(kActorHasan) == kGoalHasanIsWalkingAroundIsAtAR02) {
if (Random_Query(1, maxHasanLeaveProb) == 1
&& Player_Query_Current_Scene() != kSceneAR01
&& Player_Query_Current_Scene() != kSceneAR02
) {
// Hasan leaves Animoid Row
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsWalkingAroundIsAway);
return; // true;
} else {
// stay (change goal to a temp one to trigger GoalChanged() (so that we can reset the "track")
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsWalkingAroundStaysAtAR02);
return; // true;
}
}
if (Actor_Query_Goal_Number(kActorHasan) == kGoalHasanIsWalkingAroundIsAway) {
if (Random_Query(1, 2) == 1
&& Player_Query_Current_Scene() != kSceneAR01
&& Player_Query_Current_Scene() != kSceneAR02
) {
// Hasan returns tp Animoid Row
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsWalkingAroundIsAtAR02);
return; // true;
} else {
// stay away (change goal to a temp one to trigger GoalChanged() (so that we can reset the "track")
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsWalkingAroundStayAwayFromAR02);
return; // true;
}
}
}
}
//return false;
}
void AIScriptHasan::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHasan::ClickedByPlayer() {
//return false;
}
void AIScriptHasan::EnteredSet(int setId) {
// return false;
}
void AIScriptHasan::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHasan::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHasan::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptHasan::ShotAtAndMissed() {
// return false;
}
bool AIScriptHasan::ShotAtAndHit() {
return false;
}
void AIScriptHasan::Retired(int byActorId) {
// return false;
}
int AIScriptHasan::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHasan::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (_vm->_cutContent) {
switch (newGoalNumber) {
case kGoalHasanDefault:
Actor_Put_In_Set(kActorHasan, kSetAR01_AR02);
Actor_Set_At_XYZ(kActorHasan, -214.0f, 0.0f, -1379.0f, 371);
break;
case kGoalHasanIsAway:
Actor_Put_In_Set(kActorHasan, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorHasan, 40, 0); // kSetFreeSlotH
break;
case kGoalHasanIsWalkingAroundIsAtAR02:
AI_Movement_Track_Flush(kActorHasan);
World_Waypoint_Set(554, kSetAR01_AR02, -214.0f, 0.0f, -1379.0f);
AI_Movement_Track_Append(kActorHasan, 554, Random_Query(60, 180)); // kSetAR01_AR02
Actor_Face_Heading(kActorHasan, 371, false);
AI_Movement_Track_Repeat(kActorHasan);
break;
case kGoalHasanIsWalkingAroundIsAway:
AI_Movement_Track_Flush(kActorHasan);
AI_Movement_Track_Append(kActorHasan, 40, Random_Query(10, 40)); // kSetFreeSlotH
AI_Movement_Track_Repeat(kActorHasan);
break;
case kGoalHasanIsWalkingAroundStayAwayFromAR02:
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsWalkingAroundIsAway);
break;
case kGoalHasanIsWalkingAroundStaysAtAR02:
Actor_Set_Goal_Number(kActorHasan, kGoalHasanIsWalkingAroundIsAtAR02);
break;
}
} else {
// original behavior - Hasan leaves on Act 3
if (newGoalNumber == kGoalHasanIsAway) {
Actor_Put_In_Set(kActorHasan, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorHasan, 40, 0); // kSetFreeSlotH
}
}
return false;
}
bool AIScriptHasan::UpdateAnimation(int *animation, int *frame) {
if (_var4) {
--_var4;
}
if (_var5) {
--_var5;
}
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationHasanGestureSuggest;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanGestureSuggest)) {
_animationFrame = 0;
_varChooseIdleAnimation = 0;
*animation = kModelAnimationHasanIdleSlightMovement;
_var1 = Random_Query(6, 14);
_var2 = 2 * Random_Query(0, 1) - 1;
_var4 = Random_Query(40, 60);
}
if (_animationFrame >= 10 && _animationFrame <= 14) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 1);
}
}
} else if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationHasanTakingABiteSnakeMove;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanTakingABiteSnakeMove)) {
_animationFrame = 0;
_varChooseIdleAnimation = 0;
*animation = kModelAnimationHasanIdleSlightMovement;
_var1 = Random_Query(6, 14);
_var2 = 2 * Random_Query(0, 1) - 1;
_var5 = Random_Query(40, 60);
}
if (_animationFrame == 14) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(3, 10);
}
if (_animationFrame == 23) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 4);
}
}
} else if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationHasanIdleSlightMovement;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
_animationFrame += _var2;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanIdleSlightMovement)) {
_animationFrame = 0;
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanIdleSlightMovement) - 1;
}
if (!--_var1) {
_var2 = 2 * Random_Query(0, 1) - 1;
_var1 = Random_Query(6, 14);
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 4);
}
if (_animationFrame == 0) {
_varChooseIdleAnimation = Random_Query(0, 2);
}
if (_varChooseIdleAnimation == 1 && _var4) {
_varChooseIdleAnimation = 0;
}
if (_varChooseIdleAnimation == 2 && _var5) {
_varChooseIdleAnimation = 0;
}
}
}
break;
case 1:
*animation = kModelAnimationHasanTalkMovingBothHands;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanTalkMovingBothHands)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationHasanTalkLeftRightLeftGesture;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanTalkLeftRightLeftGesture)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationHasanTalkMovingBothHands;
}
break;
case 3:
*animation = kModelAnimationHasanTalkRaiseHandSnakeMove;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanTalkRaiseHandSnakeMove)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationHasanTalkMovingBothHands;
}
break;
case 4:
*animation = kModelAnimationHasanTalkMovingBothHandsAndNod;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanTalkMovingBothHandsAndNod)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationHasanTalkMovingBothHands;
}
break;
case 5:
*animation = kModelAnimationHasanTalkWipeFaceLeftHand02;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanTalkWipeFaceLeftHand02)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationHasanTalkMovingBothHands;
}
break;
case 6:
*animation = kModelAnimationHasanTalkUpset;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHasanTalkUpset)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationHasanTalkMovingBothHands;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptHasan::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptHasan::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_varChooseIdleAnimation = 0;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 1;
_varChooseIdleAnimation = 0;
_animationFrame = 0;
break;
case 12:
// fall through
case 13:
// fall through
case 14:
// fall through
case 15:
// fall through
case 16:
_animationState = 6;
_varChooseIdleAnimation = 0;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptHasan::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptHasan::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHasan::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHasan::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptHasan::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,452 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHawkersBarkeep::AIScriptHawkersBarkeep(BladeRunnerEngine *vm) : AIScriptBase(vm) {
// _varChooseIdleAnimation can have valid values: 0, 1, 2s
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
_var3 = 1;
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptHawkersBarkeep::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
_var3 = 1;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorHawkersBarkeep, kSetHC01_HC02_HC03_HC04);
Actor_Set_At_XYZ(kActorHawkersBarkeep, -225.0f, 0.14f, 39.0f, 284);
}
bool AIScriptHawkersBarkeep::Update() {
return false;
}
void AIScriptHawkersBarkeep::TimerExpired(int timer) {
//return false;
}
void AIScriptHawkersBarkeep::CompletedMovementTrack() {
//return false;
}
void AIScriptHawkersBarkeep::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHawkersBarkeep::ClickedByPlayer() {
//return false;
}
void AIScriptHawkersBarkeep::EnteredSet(int setId) {
// return false;
}
void AIScriptHawkersBarkeep::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHawkersBarkeep::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHawkersBarkeep::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptHawkersBarkeep::ShotAtAndMissed() {
// return false;
}
bool AIScriptHawkersBarkeep::ShotAtAndHit() {
return false;
}
void AIScriptHawkersBarkeep::Retired(int byActorId) {
// return false;
}
int AIScriptHawkersBarkeep::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHawkersBarkeep::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 1) {
_animationState = 8;
_animationFrame = -1;
Actor_Set_Goal_Number(kActorHawkersBarkeep, 0);
return true;
} else if (newGoalNumber == 2) {
_animationState = 9;
_animationFrame = -1;
Actor_Set_Goal_Number(kActorHawkersBarkeep, 0);
return true;
}
return false;
}
bool AIScriptHawkersBarkeep::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationHawkersBarkeepIdle;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
if (Random_Query(0, 6) == 0) {
_var3 = -_var3;
}
} else {
_animationFrame += _var3;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepIdle))
_animationFrame = 0;
if (_animationFrame < 0)
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepIdle) - 1;
if (!Random_Query(0, 4))
_varNumOfTimesToHoldCurrentFrame = 1;
if (_animationFrame == 13 || _animationFrame == 5 || _animationFrame == 9)
_varNumOfTimesToHoldCurrentFrame = Random_Query(2, 8);
if (!Random_Query(0, 5)) {
if (_animationFrame == 0 || _animationFrame == 11) {
_animationFrame = 0;
if (Random_Query(0, 1)) {
*animation = kModelAnimationHawkersBarkeepCleaningBar;
_varChooseIdleAnimation = 1;
} else {
*animation = kModelAnimationHawkersBarkeepWipingGlasses;
_varChooseIdleAnimation = 2;
}
}
}
}
} else if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationHawkersBarkeepCleaningBar;
if (_animationFrame <= 3)
_var3 = 1;
if (_animationFrame == 11) {
if (Random_Query(0, 2))
_var3 = -1;
}
_animationFrame += _var3;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepCleaningBar)) {
*animation = kModelAnimationHawkersBarkeepIdle;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
} else if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationHawkersBarkeepWipingGlasses;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
if (_varNumOfTimesToHoldCurrentFrame == 0)
_var3 = 2 * Random_Query(0, 1) - 1;
} else {
if (_animationFrame <= 11)
_var3 = 1;
if (_animationFrame == 14) {
if (Random_Query(0, 2) != 0) {
_var3 = -1;
}
}
if (_animationFrame == 18) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(5, 15);
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepWipingGlasses)) {
*animation = kModelAnimationHawkersBarkeepIdle;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
}
}
}
break;
case 1:
if (_varChooseIdleAnimation == 0) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
} else if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationHawkersBarkeepCleaningBar;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepCleaningBar)) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
} else if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationHawkersBarkeepWipingGlasses;
_animationFrame += 2;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepWipingGlasses)) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
}
break;
case 2:
*animation = kModelAnimationHawkersBarkeepCalmTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepCalmTalk)) {
_animationFrame = 0;
}
}
break;
case 3:
*animation = kModelAnimationHawkersBarkeepExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepExplainTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationHawkersBarkeepCalmTalk;
}
break;
case 4:
*animation = kModelAnimationHawkersBarkeepBentsAndWipesTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepBentsAndWipesTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationHawkersBarkeepCalmTalk;
}
break;
case 5:
*animation = kModelAnimationHawkersBarkeepAltGestureGiveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepAltGestureGiveTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationHawkersBarkeepCalmTalk;
}
break;
case 6:
*animation = kModelAnimationHawkersBarkeepBentingTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepBentingTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationHawkersBarkeepCalmTalk;
}
break;
case 7:
*animation = kModelAnimationHawkersBarkeepBentingAndDismissTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepBentingAndDismissTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationHawkersBarkeepCalmTalk;
}
break;
case 8:
*animation = kModelAnimationHawkersBarkeepGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepGestureGive)) {
*animation = kModelAnimationHawkersBarkeepIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 9:
*animation = kModelAnimationHawkersBarkeepGiveMoonshine;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHawkersBarkeepGiveMoonshine)) {
*animation = kModelAnimationHawkersBarkeepIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptHawkersBarkeep::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptHawkersBarkeep::ChangeAnimationMode(int mode) {
switch (mode) {
case 0:
if (_animationState >= 2 && _animationState <= 7) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case 3:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 1;
_animationStateNext = 2;
_animationNext = kModelAnimationHawkersBarkeepCalmTalk;
}
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 1;
_animationStateNext = 3;
_animationNext = kModelAnimationHawkersBarkeepExplainTalk;
}
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 1;
_animationStateNext = 4;
_animationNext = kModelAnimationHawkersBarkeepBentsAndWipesTalk;
}
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 1;
_animationStateNext = 5;
_animationNext = kModelAnimationHawkersBarkeepAltGestureGiveTalk;
}
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 1;
_animationStateNext = 6;
_animationNext = kModelAnimationHawkersBarkeepBentingTalk;
}
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 16:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 1;
_animationStateNext = 7;
_animationNext = kModelAnimationHawkersBarkeepBentingAndDismissTalk;
}
_resumeIdleAfterFramesetCompletesFlag = false;
break;
default:
debugC(6, kDebugAnimation, "AIScriptHawkersBarkeep::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptHawkersBarkeep::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHawkersBarkeep::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHawkersBarkeep::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptHawkersBarkeep::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHawkersParrot::AIScriptHawkersParrot(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptHawkersParrot::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptHawkersParrot::Update() {
return false;
}
void AIScriptHawkersParrot::TimerExpired(int timer) {
//return false;
}
void AIScriptHawkersParrot::CompletedMovementTrack() {
//return false;
}
void AIScriptHawkersParrot::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHawkersParrot::ClickedByPlayer() {
//return false;
}
void AIScriptHawkersParrot::EnteredSet(int setId) {
// return false;
}
void AIScriptHawkersParrot::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHawkersParrot::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHawkersParrot::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptHawkersParrot::ShotAtAndMissed() {
// return false;
}
bool AIScriptHawkersParrot::ShotAtAndHit() {
return false;
}
void AIScriptHawkersParrot::Retired(int byActorId) {
// return false;
}
int AIScriptHawkersParrot::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHawkersParrot::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptHawkersParrot::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptHawkersParrot::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptHawkersParrot::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHawkersParrot::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHawkersParrot::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptHawkersParrot::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,363 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHolloway::AIScriptHolloway(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptHolloway::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayDefault);
}
bool AIScriptHolloway::Update() {
if (Actor_Query_Goal_Number(kActorHolloway) == kGoalHollowayPrepareCaptureMcCoy) {
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayCaptureMcCoy);
}
return false;
}
void AIScriptHolloway::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask0) {
AI_Countdown_Timer_Reset(kActorHolloway, kActorTimerAIScriptCustomTask0);
if (Global_Variable_Query(kVariableHollowayArrest) == 1) {
Player_Gains_Control();
}
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayTalkToMcCoy);
}
}
void AIScriptHolloway::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorHolloway) < 245
&& Actor_Query_Goal_Number(kActorHolloway) > 239
) {
Loop_Actor_Walk_To_Actor(kActorHolloway, kActorMcCoy, 24, false, false);
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayApproachMcCoy);
}
}
void AIScriptHolloway::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHolloway::ClickedByPlayer() {
//return false;
}
void AIScriptHolloway::EnteredSet(int setId) {
// return false;
}
void AIScriptHolloway::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHolloway::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHolloway::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (otherActorId == kActorMcCoy
&& Actor_Query_Goal_Number(kActorHolloway) == kGoalHollowayApproachMcCoy
) {
AI_Countdown_Timer_Reset(kActorHolloway, kActorTimerAIScriptCustomTask0);
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayKnockOutMcCoy);
}
}
void AIScriptHolloway::ShotAtAndMissed() {
// return false;
}
bool AIScriptHolloway::ShotAtAndHit() {
return false;
}
void AIScriptHolloway::Retired(int byActorId) {
// return false;
}
int AIScriptHolloway::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHolloway::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalHollowayGoToNR07:
Actor_Put_In_Set(kActorHolloway, kSetNR07);
Actor_Set_At_XYZ(kActorHolloway, -102.0f, -73.5f, -233.0f, 0);
Player_Loses_Control();
AI_Movement_Track_Flush(kActorHolloway);
AI_Movement_Track_Append(kActorHolloway, 336, 1);
AI_Movement_Track_Repeat(kActorHolloway);
break;
case kGoalHollowayGoToNR02:
Player_Loses_Control();
AI_Movement_Track_Flush(kActorHolloway);
AI_Movement_Track_Append(kActorHolloway, 375, 0);
AI_Movement_Track_Append(kActorHolloway, 376, 0);
AI_Movement_Track_Repeat(kActorHolloway);
break;
case kGoalHollowayGoToHF03:
Player_Loses_Control();
AI_Movement_Track_Flush(kActorHolloway);
AI_Movement_Track_Append(kActorHolloway, 372, 0);
AI_Movement_Track_Repeat(kActorHolloway);
break;
case kGoalHollowayApproachMcCoy:
Scene_Exits_Disable();
Actor_Says(kActorHolloway, 20, kAnimationModeTalk);
Actor_Face_Actor(kActorHolloway, kActorMcCoy, true);
if (Player_Query_Combat_Mode()) {
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayKnockOutMcCoy);
} else {
Actor_Says(kActorHolloway, 30, kAnimationModeTalk);
Actor_Face_Actor(kActorMcCoy, kActorHolloway, true);
AI_Countdown_Timer_Reset(kActorHolloway, kActorTimerAIScriptCustomTask0);
AI_Countdown_Timer_Start(kActorHolloway, kActorTimerAIScriptCustomTask0, 1);
}
break;
case kGoalHollowayTalkToMcCoy:
Actor_Face_Actor(kActorMcCoy, kActorHolloway, true);
Actor_Says(kActorMcCoy, 6130, 15);
Actor_Says(kActorHolloway, 40, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 6135, 13);
Actor_Says(kActorHolloway, 50, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 6140, 16);
Actor_Says(kActorHolloway, 60, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 6145, 12);
Actor_Says(kActorHolloway, 70, kAnimationModeTalk);
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayKnockOutMcCoy);
break;
case kGoalHollowayKnockOutMcCoy:
Player_Loses_Control();
Actor_Change_Animation_Mode(kActorHolloway, kAnimationModeCombatAttack);
break;
case kGoalHollowayCaptureMcCoy:
Ambient_Sounds_Remove_All_Non_Looping_Sounds(true);
Ambient_Sounds_Remove_All_Looping_Sounds(1u);
Player_Gains_Control();
Outtake_Play(kOuttakeInterrogation, false, 1);
if (Global_Variable_Query(kVariableHollowayArrest) == 1) {
Actor_Set_Goal_Number(kActorDektora, kGoalDektoraNR08ReadyToRun);
Actor_Change_Animation_Mode(kActorDektora, kAnimationModeIdle);
}
Player_Gains_Control();
Game_Flag_Set(kFlagMcCoyCapturedByHolloway);
Scene_Exits_Enable();
Actor_Set_Goal_Number(kActorSteele, kGoalSteeleNR01WaitForMcCoy);
Actor_Put_In_Set(kActorHolloway, kSetFreeSlotI);
Actor_Set_At_Waypoint(kActorHolloway, 41, 0);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeIdle);
if (Global_Variable_Query(kVariableHollowayArrest) != 1) {
Player_Gains_Control();
}
Game_Flag_Set(kFlagUG03toUG04);
Set_Enter(kSetUG04, kSceneUG04);
break;
default:
break;
}
return false;
}
bool AIScriptHolloway::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationHollowayIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHollowayIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationHollowayGlobAttack;
++_animationFrame;
if (_animationFrame == 9) {
Ambient_Sounds_Play_Sound(kSfxKICK1, 90, 99, 0, 0);
}
if (_animationFrame == 10) {
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHollowayGlobAttack)) {
Actor_Change_Animation_Mode(kActorHolloway, kAnimationModeIdle);
_animationFrame = 0;
_animationState = 0;
*animation = kModelAnimationHollowayIdle;
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayPrepareCaptureMcCoy);
}
break;
case 2:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationHollowayIdle;
_animationState = 0;
} else {
*animation = kModelAnimationHollowayCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHollowayCalmTalk)) {
_animationFrame = 0;
}
}
break;
case 3:
// fall through
case 4:
// fall through
case 5:
// fall through
case 6:
*animation = kModelAnimationHollowayExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHollowayExplainTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationHollowayCalmTalk;
}
break;
case 7:
*animation = kModelAnimationHollowayWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHollowayWalking)) {
_animationFrame = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptHolloway::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptHolloway::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState > 6) {
_animationState = 0;
_animationFrame = 0;
} else {
_resumeIdleAfterFramesetCompletesFlag = true;
}
break;
case kAnimationModeWalk:
_animationState = 7;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case kAnimationModeCombatAttack:
_animationState = 1;
_animationFrame = 0;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
default:
debugC(6, kDebugAnimation, "AIScriptHolloway::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptHolloway::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHolloway::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHolloway::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptHolloway::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,542 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHowieLee::AIScriptHowieLee(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_varIdleStatesToggle = 0;
}
void AIScriptHowieLee::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_varIdleStatesToggle = 0;
Actor_Put_In_Set(kActorHowieLee, kSetCT01_CT12);
Actor_Set_At_Waypoint(kActorHowieLee, 67, 605); // in kSetCT01_CT12
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
}
bool AIScriptHowieLee::Update() {
if (_vm->_cutContent) {
// keep Howie in Acts 2 and 3
// Howie in Acts 2 and 3 will have a routine with existing waypoints/goals,
// so no need to add new goals (> 100) for those Acts
if (Actor_Query_Goal_Number(kActorHowieLee) < 100
&& Global_Variable_Query(kVariableChapter) == 4
) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToFreeSlotC);
}
if (Global_Variable_Query(kVariableChapter) > 3) {
return true;
}
} else {
if (Actor_Query_Goal_Number(kActorHowieLee) < 100
&& Global_Variable_Query(kVariableChapter) == 2
) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToFreeSlotC);
}
if (Global_Variable_Query(kVariableChapter) > 1) {
return true;
}
}
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeDefault) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeMovesInDiner01);
}
// In the original code this is used (in Act 1) to get Howie back to the Diner
// from goals kGoalHowieLeeGoesToCT04GarbageBin or kGoalHowieLeeGoesToFreeSlotH
// It might cause a blink-in issue, depending when update() will be called for Howie
// This is kept as a backup while similar code is placed in the CT01 and CT02 scenes InitializeScene()
// that will handle Howie appearing there immediately (fix for blink in)
if (Game_Flag_Query(kFlagMcCoyInChinaTown)
&& !Actor_Query_In_Set(kActorHowieLee, kSetCT01_CT12)) {
AI_Movement_Track_Flush(kActorHowieLee);
AI_Movement_Track_Append(kActorHowieLee, 67, 0); // in kSetCT01_CT12
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
}
#if BLADERUNNER_ORIGINAL_BUGS
if ( Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner01
&& Game_Flag_Query(kFlagCT01BoughtHowieLeeFood)
&& !Game_Flag_Query(kFlagMcCoyInChinaTown) ) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
return true;
}
#else
// Prevents possibility of Howie Lee from blinking in/out of existence
// when the fly-out loop is playing and/or when McCoy enters and exits the Spinner with the spinner doors animation restored
if ((Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner01
|| Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner02
|| Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner03
|| Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner06
|| Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeDefault)
&& Game_Flag_Query(kFlagCT01BoughtHowieLeeFood)
&& !Game_Flag_Query(kFlagMcCoyInChinaTown)
&& Player_Query_Current_Scene() != kSceneCT01
&& Player_Query_Current_Scene() != kSceneCT12
) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
return true;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
return false;
}
void AIScriptHowieLee::TimerExpired(int timer) {
//return false;
}
void AIScriptHowieLee::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner01) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeMovesInDiner02);
return; // true;
}
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner02) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeMovesInDiner03);
return; // true;
}
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner03) {
if (_vm->_cutContent) {
//
// *after Act 1* Howie will be going to the Garbage Bin "semi-regularly"
// if McCoy is not in scenes CT01 and CT12 (where Howie is visible working at the diner)
// otherwise he'll do the short cycle (goals 0, 1, 2, 3)
if (Global_Variable_Query(kVariableChapter) > 1
&& Player_Query_Current_Scene() != kSceneCT01
&& Player_Query_Current_Scene() != kSceneCT12
&& Player_Query_Current_Scene() != kSceneCT04
&& Random_Query(1, 5) == 1
) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
return; // true;
} else {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
return; // true;
}
} else {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
return; // true;
}
}
#if BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeMovesInDiner03) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
return; // true;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeGoesToCT04GarbageBin) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToFreeSlotH);
return; // true;
}
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeGoesToFreeSlotH) {
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
return; // true;
#else
// don't blink-in and also only return to diner routine if McCoy is actually in Chinatown
if (Game_Flag_Query(kFlagMcCoyInChinaTown)
&& Player_Query_Current_Scene() != kSceneCT01
&& Player_Query_Current_Scene() != kSceneCT12
) {
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
return; // true;
} else {
// return to "garbage bin" goal instead of blinking in
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeGoesToCT04GarbageBin);
return; // true;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
}
// return false;
}
void AIScriptHowieLee::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHowieLee::ClickedByPlayer() {
//return false;
}
void AIScriptHowieLee::EnteredSet(int setId) {
if (Actor_Query_Goal_Number(kActorHowieLee) == kGoalHowieLeeGoesToCT04GarbageBin
&& Actor_Query_In_Set(kActorHowieLee, kSetCT03_CT04)
) {
if ( Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)
&& !Game_Flag_Query(kFlagCT04HomelessBodyInDumpster)
&& !Game_Flag_Query(kFlagCT04HomelessBodyFound)
#if BLADERUNNER_ORIGINAL_BUGS
#else
&& !Game_Flag_Query(kFlagCT04HomelessBodyThrownAway)
#endif // BLADERUNNER_ORIGINAL_BUGS
) {
Game_Flag_Set(kFlagCT04HomelessBodyFound);
// return false;
}
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)
&& Game_Flag_Query(kFlagCT04HomelessBodyInDumpster)
&& !Game_Flag_Query(kFlagCT04HomelessBodyFound)
#if BLADERUNNER_ORIGINAL_BUGS
#else
&& !Game_Flag_Query(kFlagCT04HomelessBodyThrownAway)
#endif // BLADERUNNER_ORIGINAL_BUGS
&& Random_Query(1, 10) == 1
) {
Game_Flag_Set(kFlagCT04HomelessBodyFound);
// return true;
}
// return false;
}
}
void AIScriptHowieLee::OtherAgentEnteredThisSet(int otherActorId) {
#if BLADERUNNER_ORIGINAL_BUGS
#else
// prevent player from actually meeting hovering Howie half-body in kSetCT03_CT04
if (otherActorId == kActorMcCoy
&& Actor_Query_In_Set(kActorHowieLee, kSetCT03_CT04)
) {
AI_Movement_Track_Flush(kActorHowieLee);
AI_Movement_Track_Append(kActorHowieLee, 67, 0); // in kSetCT01_CT12
Actor_Set_Goal_Number(kActorHowieLee, kGoalHowieLeeDefault);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// return false;
}
void AIScriptHowieLee::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHowieLee::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptHowieLee::ShotAtAndMissed() {
// return false;
}
bool AIScriptHowieLee::ShotAtAndHit() {
return false;
}
void AIScriptHowieLee::Retired(int byActorId) {
// return false;
}
int AIScriptHowieLee::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHowieLee::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalHowieLeeMovesInDiner01:
AI_Movement_Track_Flush(kActorHowieLee);
if (Random_Query(1, 2) == 1) {
AI_Movement_Track_Append_With_Facing(kActorHowieLee, 67, Random_Query(3, 10), 720); // in kSetCT01_CT12
} else {
AI_Movement_Track_Append_With_Facing(kActorHowieLee, 69, Random_Query(3, 10), 640); // in kSetCT01_CT12
}
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
case kGoalHowieLeeMovesInDiner02:
AI_Movement_Track_Flush(kActorHowieLee);
if (Random_Query(1, 2) == 1) {
AI_Movement_Track_Append_With_Facing(kActorHowieLee, 68, Random_Query(3, 10), 641); // in kSetCT01_CT12
} else {
AI_Movement_Track_Append_With_Facing(kActorHowieLee, 67, Random_Query(3, 10), 720); // in kSetCT01_CT12
}
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
case kGoalHowieLeeMovesInDiner03:
AI_Movement_Track_Flush(kActorHowieLee);
if (Random_Query(1, 2) == 1) {
AI_Movement_Track_Append_With_Facing(kActorHowieLee, 69, Random_Query(3, 10), 640); // in kSetCT01_CT12
} else {
AI_Movement_Track_Append_With_Facing(kActorHowieLee, 68, Random_Query(3, 10), 641); // in kSetCT01_CT12
}
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
case kGoalHowieLeeGoesToCT04GarbageBin:
AI_Movement_Track_Flush(kActorHowieLee);
AI_Movement_Track_Append(kActorHowieLee, 66, 30); // in kSetCT03_CT04
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
case kGoalHowieLeeGoesToFreeSlotH:
AI_Movement_Track_Flush(kActorHowieLee);
AI_Movement_Track_Append(kActorHowieLee, 40, 60); // in kSetFreeSlotH
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
case kGoalHowieLeeMovesInDiner06: // Unused goal?
AI_Movement_Track_Flush(kActorHowieLee);
AI_Movement_Track_Append(kActorHowieLee, 67, 90); // in kSetCT01_CT12
AI_Movement_Track_Repeat(kActorHowieLee);
return true;
case kGoalHowieLeeStopMoving:
AI_Movement_Track_Flush(kActorHowieLee);
return false;
case kGoalHowieLeeGoesToFreeSlotC:
AI_Movement_Track_Flush(kActorHowieLee);
Actor_Put_In_Set(kActorHowieLee, kSetFreeSlotC);
Actor_Set_At_Waypoint(kActorHowieLee, 35, 0); // in kSetFreeSlotC
return false;
}
return false;
}
bool AIScriptHowieLee::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
++_animationFrame;
// _varIdleStatesToggle can be 0 or 1.
// Determines whether kModelAnimationHowieLeePutsIngredientsCooking or kModelAnimationHowieLeeGathersOfTidiesUp is used.
if (_varIdleStatesToggle > 0) {
*animation = kModelAnimationHowieLeePutsIngredientsCooking;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeePutsIngredientsCooking)) {
_animationFrame = 0;
if (Random_Query(0, 2) > 0) {
_varIdleStatesToggle ^= 1;
}
}
} else {
*animation = kModelAnimationHowieLeeGathersOfTidiesUp;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeGathersOfTidiesUp)) {
_animationFrame = 0;
if (Random_Query(0, 1) > 0) {
_varIdleStatesToggle ^= 1;
}
}
}
break;
case 1:
*animation = kModelAnimationHowieLeeLongGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeLongGestureGive)) {
_animationFrame = 0;
if (_animationState < 3 || _animationState > 8) {
_animationState = 0;
_animationFrame = 0;
_varIdleStatesToggle = Random_Query(0, 1);
} else {
Game_Flag_Set(kFlagHowieLeeAnimation1);
}
*animation = kModelAnimationHowieLeePutsIngredientsCooking;
}
break;
case 2:
*animation = kModelAnimationHowieLeeWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeWalking)) {
_animationFrame = 0;
}
break;
case 3:
if (Game_Flag_Query(kFlagHowieLeeAnimation1)) {
Game_Flag_Reset(kFlagHowieLeeAnimation1);
_animationState = 0;
_animationFrame = 0;
_varIdleStatesToggle = Random_Query(0, 1);
*animation = kModelAnimationHowieLeeGathersOfTidiesUp;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeCalmTalk)) {
_animationFrame = 0;
}
*animation = kModelAnimationHowieLeeCalmTalk;
}
break;
case 4:
*animation = kModelAnimationHowieLeeExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeExplainTalk)) {
_animationState = 3;
_animationFrame = 0;
*animation = kModelAnimationHowieLeeCalmTalk;
}
break;
case 5:
*animation = kModelAnimationHowieLeeUpsetTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeUpsetTalk)) {
_animationState = 3;
_animationFrame = 0;
*animation = kModelAnimationHowieLeeCalmTalk;
}
break;
case 6:
*animation = kModelAnimationHowieLeeAngryTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeAngryTalk)) {
_animationState = 3;
_animationFrame = 0;
*animation = kModelAnimationHowieLeeCalmTalk;
}
break;
case 7:
*animation = kModelAnimationHowieLeeNoTimeTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeNoTimeTalk)) {
_animationState = 3;
_animationFrame = 0;
*animation = kModelAnimationHowieLeeCalmTalk;
}
break;
case 8:
*animation = kModelAnimationHowieLeeElaborateMovementTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationHowieLeeElaborateMovementTalk)) {
_animationState = 3;
_animationFrame = 0;
*animation = kModelAnimationHowieLeeCalmTalk;
}
break;
default:
// Dummy placeholder, kModelAnimationZubenWalking (399) is a Zuben animation
*animation = kModelAnimationZubenWalking;
debugC(6, kDebugAnimation, "AIScriptHowieLee::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptHowieLee::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState < 3 || _animationState > 8) {
_animationState = 0;
_animationFrame = 0;
_varIdleStatesToggle = Random_Query(0, 1);
} else {
Game_Flag_Set(kFlagHowieLeeAnimation1);
}
break;
case kAnimationModeWalk:
if (_animationState != 2) {
_animationState = 2;
_animationFrame = 0;
}
break;
case kAnimationModeTalk:
_animationState = 3;
_animationFrame = 0;
break;
case 12:
_animationState = 4;
_animationFrame = 0;
break;
case 13:
_animationState = 5;
_animationFrame = 0;
break;
case 14:
_animationState = 6;
_animationFrame = 0;
break;
case 15:
_animationState = 7;
_animationFrame = 0;
break;
case 16:
_animationState = 8;
_animationFrame = 0;
break;
case 43:
_animationState = 1;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptHowieLee::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptHowieLee::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHowieLee::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHowieLee::ReachedMovementTrackWaypoint(int waypointId) {
if (waypointId == 67 && Random_Query(1, 2) == 2) {
Actor_Face_Heading(kActorHowieLee, 850, 0);
_animationFrame = 0;
_animationState = 1;
}
return true;
}
void AIScriptHowieLee::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,169 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHysteriaPatron1::AIScriptHysteriaPatron1(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptHysteriaPatron1::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
Actor_Put_In_Set(kActorHysteriaPatron1, kSetNR03);
Actor_Set_At_XYZ(kActorHysteriaPatron1, 50.0f, -6.59f, -1030.0f, 524);
}
bool AIScriptHysteriaPatron1::Update() {
return false;
}
void AIScriptHysteriaPatron1::TimerExpired(int timer) {
//return false;
}
void AIScriptHysteriaPatron1::CompletedMovementTrack() {
//return false;
}
void AIScriptHysteriaPatron1::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHysteriaPatron1::ClickedByPlayer() {
//return false;
}
void AIScriptHysteriaPatron1::EnteredSet(int setId) {
// return false;
}
void AIScriptHysteriaPatron1::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHysteriaPatron1::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHysteriaPatron1::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptHysteriaPatron1::ShotAtAndMissed() {
// return false;
}
bool AIScriptHysteriaPatron1::ShotAtAndHit() {
return false;
}
void AIScriptHysteriaPatron1::Retired(int byActorId) {
// return false;
}
int AIScriptHysteriaPatron1::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHysteriaPatron1::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
const int kAnimationsCount = 27;
const int animationList[kAnimationsCount] = {
kModelAnimationHysteriaPatron1DanceStandingUpSemiSitAndUp, kModelAnimationHysteriaPatron1DanceStandingUpLeftMotion, kModelAnimationHysteriaPatron1DanceStandingUpSemiSitAndUp,
kModelAnimationHysteriaPatron1DanceStandingUpToSplits, kModelAnimationHysteriaPatron1DanceSplitsDuckAndDown, kModelAnimationHysteriaPatron1DanceSplitsSemiUpAndDown,
kModelAnimationHysteriaPatron1DanceSplitsBackAndForth, kModelAnimationHysteriaPatron1DanceSplitsToStandingUp, kModelAnimationHysteriaPatron1DanceStandingUpLeftMotion,
kModelAnimationHysteriaPatron1DanceStandingUpSemiSitAndUp, kModelAnimationHysteriaPatron1DanceStandingUpToSplits, kModelAnimationHysteriaPatron1DanceSplitsSemiUpAndDown,
kModelAnimationHysteriaPatron1DanceSplitsDuckAndDown, kModelAnimationHysteriaPatron1DanceSplitsToStandingUp, kModelAnimationHysteriaPatron1DanceStandingUpSemiSitAndUp,
kModelAnimationHysteriaPatron1DanceStandingUpSemiSitAndUp, kModelAnimationHysteriaPatron1DanceStandingUpLeftMotion, kModelAnimationHysteriaPatron1DanceStandingUpToSplits,
kModelAnimationHysteriaPatron1DanceSplitsBackAndForth, kModelAnimationHysteriaPatron1DanceSplitsToStandingUp, kModelAnimationHysteriaPatron1DanceStandingUpLeftMotion,
kModelAnimationHysteriaPatron1DanceStandingUpSemiSitAndUp, kModelAnimationHysteriaPatron1DanceStandingUpToSplits, kModelAnimationHysteriaPatron1DanceSplitsBackAndForth,
kModelAnimationHysteriaPatron1DanceSplitsDuckAndDown, kModelAnimationHysteriaPatron1DanceSplitsSemiUpAndDown, kModelAnimationHysteriaPatron1DanceSplitsToStandingUp
};
bool AIScriptHysteriaPatron1::UpdateAnimation(int *animation, int *frame) {
if (_vm->_cutContent
&& (_animationState == 2 || _animationState == 16 || _animationState == 21)
) {
// replace a few of the repeated "standing up" animations
// with the cut animation kModelAnimationHysteriaPatron1DanceStandingUpStowingMoney
*animation = kModelAnimationHysteriaPatron1DanceStandingUpStowingMoney;
} else {
*animation = animationList[_animationState];
}
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
if (++_animationState >= kAnimationsCount) {
_animationState = 0;
}
if (_vm->_cutContent
&& (_animationState == 2 || _animationState == 16 || _animationState == 21)
) {
// replace a few of the repeated "standing up" animations
// with the cut animation kModelAnimationHysteriaPatron1DanceStandingUpStowingMoney
*animation = kModelAnimationHysteriaPatron1DanceStandingUpStowingMoney;
} else {
*animation = animationList[_animationState];
}
}
*frame = _animationFrame;
return true;
}
bool AIScriptHysteriaPatron1::ChangeAnimationMode(int mode) {
debugC(6, kDebugAnimation, "AIScriptHysteriaPatron1::ChangeAnimationMode(%d) - Animation mode change is not supported", mode);
return true;
}
void AIScriptHysteriaPatron1::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHysteriaPatron1::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHysteriaPatron1::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptHysteriaPatron1::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,154 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHysteriaPatron2::AIScriptHysteriaPatron2(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptHysteriaPatron2::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
Actor_Put_In_Set(kActorHysteriaPatron2, kSetNR05_NR08);
Actor_Set_At_XYZ(kActorHysteriaPatron2, -516.0f, 0.0f, -190.0f, 452);
}
bool AIScriptHysteriaPatron2::Update() {
return false;
}
void AIScriptHysteriaPatron2::TimerExpired(int timer) {
//return false;
}
void AIScriptHysteriaPatron2::CompletedMovementTrack() {
//return false;
}
void AIScriptHysteriaPatron2::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHysteriaPatron2::ClickedByPlayer() {
Actor_Face_Actor(kActorMcCoy, kActorHysteriaPatron2, true);
Actor_Says(kActorMcCoy, 8935, kAnimationModeTalk);
}
void AIScriptHysteriaPatron2::EnteredSet(int setId) {
// return false;
}
void AIScriptHysteriaPatron2::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHysteriaPatron2::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHysteriaPatron2::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptHysteriaPatron2::ShotAtAndMissed() {
// return false;
}
bool AIScriptHysteriaPatron2::ShotAtAndHit() {
return false;
}
void AIScriptHysteriaPatron2::Retired(int byActorId) {
// return false;
}
int AIScriptHysteriaPatron2::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHysteriaPatron2::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
const int kAnimationsCount = 30;
const int animationList[kAnimationsCount] = {
kModelAnimationHysteriaPatron2DanceHandsBellyMotion, kModelAnimationHysteriaPatron2DanceHandsUpLeftMotion, kModelAnimationHysteriaPatron2DanceHandsUpSitAndUp,
kModelAnimationHysteriaPatron2DanceHandsUpToHandsDown, kModelAnimationHysteriaPatron2DanceHandsDownHipsSwirl, kModelAnimationHysteriaPatron2DanceHandsDownLegSwirl,
kModelAnimationHysteriaPatron2DanceHandsDownLeanBackForth, kModelAnimationHysteriaPatron2DanceHandsDownToHandsUp, kModelAnimationHysteriaPatron2DanceHandsUpLeftMotion,
kModelAnimationHysteriaPatron2DanceHandsBellyMotion, kModelAnimationHysteriaPatron2DanceHandsBellyMotion, kModelAnimationHysteriaPatron2DanceHandsBellyMotion,
kModelAnimationHysteriaPatron2DanceHandsBellyMotion, kModelAnimationHysteriaPatron2DanceHandsUpLeftMotion, kModelAnimationHysteriaPatron2DanceHandsUpToHandsDown,
kModelAnimationHysteriaPatron2DanceHandsDownLegSwirl, kModelAnimationHysteriaPatron2DanceHandsDownHipsSwirl, kModelAnimationHysteriaPatron2DanceHandsDownLeanBackForth,
kModelAnimationHysteriaPatron2DanceHandsDownToHandsUp, kModelAnimationHysteriaPatron2DanceHandsUpSitAndUp, kModelAnimationHysteriaPatron2DanceHandsBellyMotion,
kModelAnimationHysteriaPatron2DanceHandsBellyMotion, kModelAnimationHysteriaPatron2DanceHandsBellyMotion, kModelAnimationHysteriaPatron2DanceHandsBellyMotion,
kModelAnimationHysteriaPatron2DanceHandsBellyMotion, kModelAnimationHysteriaPatron2DanceHandsUpToHandsDown, kModelAnimationHysteriaPatron2DanceHandsDownHipsSwirl,
kModelAnimationHysteriaPatron2DanceHandsDownHipsSwirl, kModelAnimationHysteriaPatron2DanceHandsDownLeanBackForth, kModelAnimationHysteriaPatron2DanceHandsDownToHandsUp
};
bool AIScriptHysteriaPatron2::UpdateAnimation(int *animation, int *frame) {
*animation = animationList[_animationState];
if (++_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
if (++_animationState >= kAnimationsCount)
_animationState = 0;
*animation = animationList[_animationState];
}
*frame = _animationFrame;
return true;
}
bool AIScriptHysteriaPatron2::ChangeAnimationMode(int mode) {
debugC(6, kDebugAnimation, "AIScriptHysteriaPatron2::ChangeAnimationMode(%d) - Animation mode change is not supported", mode);
return true;
}
void AIScriptHysteriaPatron2::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHysteriaPatron2::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHysteriaPatron2::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptHysteriaPatron2::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,172 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptHysteriaPatron3::AIScriptHysteriaPatron3(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptHysteriaPatron3::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
if (_vm->_cutContent) {
Actor_Put_In_Set(kActorHysteriaPatron3, kSetNR05_NR08);
Actor_Set_At_XYZ(kActorHysteriaPatron3, -600.0f, 0.0f, -245.0f, 880);
}
}
bool AIScriptHysteriaPatron3::Update() {
return false;
}
void AIScriptHysteriaPatron3::TimerExpired(int timer) {
//return false;
}
void AIScriptHysteriaPatron3::CompletedMovementTrack() {
//return false;
}
void AIScriptHysteriaPatron3::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptHysteriaPatron3::ClickedByPlayer() {
if (_vm->_cutContent) {
Actor_Face_Actor(kActorMcCoy, kActorHysteriaPatron3, true);
Actor_Says(kActorMcCoy, 8935, kAnimationModeTalk);
}
//return false;
}
void AIScriptHysteriaPatron3::EnteredSet(int setId) {
// return false;
}
void AIScriptHysteriaPatron3::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptHysteriaPatron3::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptHysteriaPatron3::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptHysteriaPatron3::ShotAtAndMissed() {
// return false;
}
bool AIScriptHysteriaPatron3::ShotAtAndHit() {
return false;
}
void AIScriptHysteriaPatron3::Retired(int byActorId) {
// return false;
}
int AIScriptHysteriaPatron3::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptHysteriaPatron3::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
const int kAnimationsCount = 3;
const int animationList[kAnimationsCount] = {
kModelAnimationHysteriaPatron3DanceHandsDownLeanBackForth,
kModelAnimationHysteriaPatron3DanceHandsDownToHandsUp,
kModelAnimationHysteriaPatron3DanceHandsDownToHandsUp,
};
bool AIScriptHysteriaPatron3::UpdateAnimation(int *animation, int *frame) {
if (_vm->_cutContent) {
if (_animationState >= kAnimationsCount) {
debugC(6, kDebugAnimation, "AIScriptHysteriaPatron3::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
} else {
*animation = animationList[_animationState];
if (_animationState == 2) {
--_animationFrame;
if (_animationFrame == 0) {
_animationState = Random_Query(0, 1); // restart the cycle from 0 or 1 state
_animationFrame = 0;
*animation = animationList[_animationState];
}
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
if (_animationState == 0 && Random_Query(0, 2) == 0) {
_animationState = 0; // restart same 0 state, with a small random chance
} else {
++_animationState;
if (_animationState == 2) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(animationList[_animationState]) - 1;
} else if (_animationState >= kAnimationsCount) {
_animationState = Random_Query(0, 1); // restart the cycle from 0 or 1 state
}
}
*animation = animationList[_animationState];
}
}
}
*frame = _animationFrame;
}
return true;
}
bool AIScriptHysteriaPatron3::ChangeAnimationMode(int mode) {
debugC(6, kDebugAnimation, "AIScriptHysteriaPatron3::ChangeAnimationMode(%d) - Animation mode change is not supported", mode);
return true;
}
void AIScriptHysteriaPatron3::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptHysteriaPatron3::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptHysteriaPatron3::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptHysteriaPatron3::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,367 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptInsectDealer::AIScriptInsectDealer(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
_state = 0;
_frameDelta = 0;
_var2 = 0; // is set on some occasions but is never checked. Unused.
_counter = 0;
}
void AIScriptInsectDealer::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_state = 0;
_frameDelta = 1;
_var2 = 6;
_counter = 0;
Actor_Put_In_Set(kActorInsectDealer, kSetAR01_AR02);
Actor_Set_At_XYZ(kActorInsectDealer, -414.0f, 0.0f, -1199.0f, 371);
Actor_Set_Goal_Number(kActorInsectDealer, 0);
}
bool AIScriptInsectDealer::Update() {
if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorInsectDealer) < 400
)
Actor_Set_Goal_Number(kActorInsectDealer, 400);
return false;
}
void AIScriptInsectDealer::TimerExpired(int timer) {
//return false;
}
void AIScriptInsectDealer::CompletedMovementTrack() {
//return false;
}
void AIScriptInsectDealer::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptInsectDealer::ClickedByPlayer() {
//return false;
}
void AIScriptInsectDealer::EnteredSet(int setId) {
// return false;
}
void AIScriptInsectDealer::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptInsectDealer::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptInsectDealer::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptInsectDealer::ShotAtAndMissed() {
// return false;
}
bool AIScriptInsectDealer::ShotAtAndHit() {
return false;
}
void AIScriptInsectDealer::Retired(int byActorId) {
// return false;
}
int AIScriptInsectDealer::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptInsectDealer::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 400) {
Actor_Put_In_Set(kActorInsectDealer, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorInsectDealer, 40, 0);
if (!Game_Flag_Query(kFlagAR02DektoraBoughtScorpions)) {
// TODO A bug? Does it not matter if Dektora is retired at this point?
// Probably a safe inconsistency to allow (setting the flag), since in Act 5 (when Insect Dealer's goal becomes 400)
// it no longer matters if Dektora purchased the scorpions or not.
// But it still may confuse debugging and tracing of what actually happened looking at a save game.
Game_Flag_Set(kFlagAR02DektoraBoughtScorpions);
#if BLADERUNNER_ORIGINAL_BUGS
Item_Remove_From_World(kItemScorpions);
#else
if (Game_Flag_Query(kFlagScorpionsInAR02)) {
Game_Flag_Reset(kFlagScorpionsInAR02);
Item_Remove_From_World(kItemScorpions);
}
#endif
}
}
return false;
}
bool AIScriptInsectDealer::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
switch (_state) {
case 0:
*animation = kModelAnimationInsectDealerSittingIdle;
if (_counter > 0) {
--_counter;
if (Random_Query(0, 6) == 0) {
_frameDelta = -_frameDelta;
}
} else {
_animationFrame += _frameDelta;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
if (Random_Query(0, 2) == 0) {
_state = 2 * Random_Query(0, 1);
}
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(*animation) - 1;
}
_counter = Random_Query(0, 1);
if (_animationFrame == 0) {
_state = Random_Query(0, 1);
}
}
break;
case 1:
*animation = kModelAnimationInsectDealerSittingScratchEarIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingScratchEarIdle)) {
*animation = kModelAnimationInsectDealerSittingIdle;
_animationFrame = 0;
_state = 0;
_var2 = Random_Query(6, 14);
_frameDelta = 2 * Random_Query(0, 1) - 1;
}
break;
case 2:
// TODO: test... actor will be stuck
break;
}
break;
case 1:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationInsectDealerSittingIdle;
_animationState = 0;
} else {
*animation = kModelAnimationInsectDealerSittingCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingCalmTalk)) {
_animationFrame = 0;
_animationState = 0;
}
}
break;
case 2:
*animation = kModelAnimationInsectDealerSittingExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingExplainTalk)) {
*animation = kModelAnimationInsectDealerSittingCalmTalk;
_animationFrame = 0;
_animationState = 1;
}
break;
case 3:
*animation = kModelAnimationInsectDealerSittingPointingTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingPointingTalk)) {
*animation = kModelAnimationInsectDealerSittingCalmTalk;
_animationFrame = 0;
_animationState = 1;
}
break;
case 4:
*animation = kModelAnimationInsectDealerSittingHeadMoveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingHeadMoveTalk)) {
*animation = kModelAnimationInsectDealerSittingCalmTalk;
_animationFrame = 0;
_animationState = 1;
}
break;
case 5:
*animation = kModelAnimationInsectDealerSittingSuggestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingSuggestTalk)) {
*animation = kModelAnimationInsectDealerSittingCalmTalk;
_animationFrame = 0;
_animationState = 1;
}
break;
case 6:
*animation = kModelAnimationInsectDealerSittingGossipTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingGossipTalk)) {
*animation = kModelAnimationInsectDealerSittingCalmTalk;
_animationFrame = 0;
_animationState = 1;
}
break;
case 7:
*animation = kModelAnimationInsectDealerSittingDescriptiveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingDescriptiveTalk)) {
*animation = kModelAnimationInsectDealerSittingCalmTalk;
_animationFrame = 0;
_animationState = 1;
}
break;
case 8:
*animation = kModelAnimationInsectDealerSittingGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationInsectDealerSittingGestureGive)) {
*animation = kModelAnimationInsectDealerSittingIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptInsectDealer::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptInsectDealer::ChangeAnimationMode(int mode) {
switch (mode) {
case 0:
if (_animationState > 0 && _animationState <= 7) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case 3:
// fall through
case 18:
// fall through
case 19:
_animationState = 1;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 16:
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 17:
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 23:
_animationState = 8;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptInsectDealer::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptInsectDealer::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptInsectDealer::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptInsectDealer::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptInsectDealer::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,471 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptIsabella::AIScriptIsabella(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_var1 = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
// _varChooseIdleAnimation can have valid values: 0,
_varChooseIdleAnimation = 0;
_var4 = 1;
}
void AIScriptIsabella::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_var1 = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
_varChooseIdleAnimation = 0;
_var4 = 1;
}
bool AIScriptIsabella::Update() {
return false;
}
void AIScriptIsabella::TimerExpired(int timer) {
//return false;
}
void AIScriptIsabella::CompletedMovementTrack() {
//return false;
}
void AIScriptIsabella::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptIsabella::ClickedByPlayer() {
//return false;
}
void AIScriptIsabella::EnteredSet(int setId) {
// return false;
}
void AIScriptIsabella::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptIsabella::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptIsabella::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptIsabella::ShotAtAndMissed() {
// return false;
}
bool AIScriptIsabella::ShotAtAndHit() {
return false;
}
void AIScriptIsabella::Retired(int byActorId) {
// return false;
}
int AIScriptIsabella::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptIsabella::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptIsabella::UpdateAnimation(int *animation, int *frame) {
bool flag;
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 1) {
*animation = kModelIsabellaPutsSpicesInSoup;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaPutsSpicesInSoup) - 1) {
_animationFrame = 0;
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaPutsSpicesInSoup) - 1;
}
if (_animationFrame == 0) {
_varChooseIdleAnimation = 0;
_var4 = 2 * Random_Query(0, 1) - 1;
}
} else if (_varChooseIdleAnimation == 0) {
*animation = kModelIsabellaIdle;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
if (_varNumOfTimesToHoldCurrentFrame == 0) {
_var4 = 2 * Random_Query(0, 1) - 1;
}
} else {
_animationFrame += _var4;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaIdle) - 1) {
_animationFrame = 0;
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaIdle) - 1;
}
if (_animationFrame == 1) {
if (!Random_Query(0, 1)) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(4, 8);
}
}
if (_animationFrame == 11) {
if (!Random_Query(0, 1)) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(4, 8);
}
}
if (_animationFrame == 16) {
if (!Random_Query(0, 1)) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(4, 8);
}
}
if (_animationFrame == 0) {
if (!Random_Query(0, 2)) {
_varChooseIdleAnimation = 1;
}
}
}
}
break;
case 1:
*animation = kModelIsabellaGestureGiveOrTake;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaGestureGiveOrTake) - 1) {
flag = true;
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaGestureGiveOrTake) - 1;
flag = true;
} else {
flag = false;
}
}
if (flag) {
*animation = kModelIsabellaIdle;
_animationState = 0;
}
break;
case 2:
*animation = kModelIsabellaCalmTalk;
if (_animationFrame < 2 && _var1) {
_animationFrame = 0;
_animationState = 0;
} else {
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaCalmTalk) - 1) {
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaCalmTalk) - 1;
}
}
if (_animationFrame == 0) {
_animationState = Random_Query(2, 3);
}
}
break;
case 3:
*animation = kModelIsabellaSuggestTalk;
if (_animationFrame < 2 && _var1) {
_animationFrame = 0;
_animationState = 0;
} else {
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaSuggestTalk) - 1) {
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaSuggestTalk) - 1;
}
}
if (_animationFrame == 0) {
*animation = kModelIsabellaCalmTalk;
_animationState = 2;
}
}
break;
case 4:
*animation = kModelIsabellaProtestTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaProtestTalk) - 1) {
flag = true;
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaProtestTalk) - 1;
flag = true;
} else {
flag = false;
}
}
if (flag) {
*animation = kModelIsabellaCalmTalk;
_animationState = 2;
}
break;
case 5:
*animation = kModelIsabellaMoreCalmTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaMoreCalmTalk) - 1) {
flag = true;
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaMoreCalmTalk) - 1;
flag = true;
} else {
flag = false;
}
}
if (flag) {
*animation = kModelIsabellaCalmTalk;
_animationState = 2;
}
break;
case 6:
*animation = kModelIsabellaLaughTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaLaughTalk) - 1) {
flag = true;
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaLaughTalk) - 1;
flag = true;
} else {
flag = false;
}
}
if (flag) {
*animation = kModelIsabellaCalmTalk;
_animationState = 2;
}
break;
case 7:
*animation = kModelIsabellaLaughTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaLaughTalk) - 1) {
flag = true;
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaLaughTalk) - 1;
flag = true;
} else {
flag = false;
}
}
if (flag) {
*animation = kModelIsabellaCalmTalk;
_animationState = 2;
}
break;
case 8:
*animation = kModelIsabellaMoreCalmTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelIsabellaMoreCalmTalk) - 1) {
flag = true;
_animationFrame = 0;
} else {
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelIsabellaMoreCalmTalk) - 1;
flag = true;
} else {
flag = false;
}
}
if (flag) {
*animation = kModelIsabellaCalmTalk;
_animationState = 2;
}
break;
case 9:
if (_varChooseIdleAnimation == 0) {
*animation = kModelIsabellaIdle;
}
if (_varChooseIdleAnimation == 1) {
*animation = kModelIsabellaPutsSpicesInSoup;
}
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame += 2;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
}
} else {
_animationFrame -= 2;
if (_animationFrame <= 0) {
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
}
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptIsabella::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
int frames = Slice_Animation_Query_Number_Of_Frames(*animation);
if (frames != -1)
_animationFrame %= frames;
else
_animationFrame = 0;
*frame = _animationFrame;
return true;
}
bool AIScriptIsabella::ChangeAnimationMode(int mode) {
switch (mode) {
case 0:
if (_animationState > 8) {
_animationState = 0;
_animationFrame = 0;
} else {
_var1 = 1;
}
break;
case 3:
// fall through
case 9:
if (_animationState < 2 || _animationState > 8) {
_animationState = 9;
_animationStateNext = 2;
_animationNext = kModelIsabellaCalmTalk;
_var1 = 0;
}
break;
case 10:
// fall through
case 12:
if (_animationState < 2 || _animationState > 8) {
_animationState = 9;
_animationStateNext = 3;
_animationNext = kModelIsabellaSuggestTalk;
_var1 = 0;
}
break;
case 11:
// fall through
case 14:
if (_animationState < 2 || _animationState > 8) {
_animationState = 9;
_animationStateNext = 5;
_animationNext = kModelIsabellaMoreCalmTalk;
_var1 = 0;
}
break;
case 13:
if (_animationState < 2 || _animationState > 8) {
_animationState = 9;
_animationStateNext = 4;
_animationNext = kModelIsabellaProtestTalk;
_var1 = 0;
}
break;
case 15:
if (_animationState < 2 || _animationState > 8) {
_animationState = 9;
_animationStateNext = 6;
_animationNext = kModelIsabellaLaughTalk;
_var1 = 0;
}
break;
case 16:
if (_animationState < 2 || _animationState > 8) {
_animationState = 9;
_animationStateNext = 7;
_animationNext = kModelIsabellaLaughTalk;
_var1 = 0;
}
break;
case 17:
if (_animationState < 2 || _animationState > 8) {
_animationState = 9;
_animationStateNext = 8;
_animationNext = kModelIsabellaMoreCalmTalk;
_var1 = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptIsabella::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptIsabella::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptIsabella::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptIsabella::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptIsabella::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,617 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptKlein::AIScriptKlein(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptKlein::Initialize() {
_animationState = 0;
_animationFrame = 0;
_animationStateNext = 0;
Actor_Put_In_Set(kActorKlein, kSetPS07);
Actor_Set_At_XYZ(kActorKlein, 338.0f, 0.22f, -612.0f, 768);
Actor_Set_Goal_Number(kActorKlein, kGoalKleinDefault);
}
bool AIScriptKlein::Update() {
if (_vm->_cutContent) {
if (Global_Variable_Query(kVariableChapter) > 3 && Actor_Query_Goal_Number(kActorKlein) < kGoalKleinAwayAtEndOfActThree) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinAwayAtEndOfActThree);
return true;
}
} else {
// original behavior - Klein disappears after Act 1
if (Global_Variable_Query(kVariableChapter) > 1 && Actor_Query_Goal_Number(kActorKlein) < kGoalKleinAwayAtEndOfActOne) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinAwayAtEndOfActOne);
return true;
}
}
if (Actor_Query_Goal_Number(kActorKlein) < kGoalKleinIsAnnoyedByMcCoyInit
&& Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) < 40
) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyInit);
}
if (Player_Query_Current_Scene() == kScenePS07 && Actor_Query_Goal_Number(kActorKlein) == kGoalKleinDefault) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinMovingInLab01);
return true;
}
if (!_vm->_cutContent) {
// Original behavior:
// The following if-clauses and flags circumvent the manual's explicit instruction
// that McCoy should upload his clues on the Mainframe, so that Dino Klein can acquire them.
if (Actor_Clue_Query(kActorMcCoy, kClueOfficersStatement)
&& !Game_Flag_Query(kFlagMcCoyHasOfficersStatement)
) {
Game_Flag_Set(kFlagMcCoyHasOfficersStatement);
}
if (Actor_Clue_Query(kActorMcCoy, kCluePaintTransfer)
&& !Game_Flag_Query(kFlagMcCoyHasPaintTransfer)
) {
Game_Flag_Set(kFlagMcCoyHasPaintTransfer);
}
if (Actor_Clue_Query(kActorMcCoy, kClueShellCasings)
&& !Game_Flag_Query(kFlagMcCoyHasShellCasings)
) {
Game_Flag_Set(kFlagMcCoyHasShellCasings);
}
if (Actor_Clue_Query(kActorMcCoy, kClueChromeDebris)
&& !Game_Flag_Query(kFlagMcCoyHasChromeDebris)
) {
Game_Flag_Set(kFlagMcCoyHasChromeDebris);
}
}
// The following deals with the case that Klein gets annoyed by McCoy
if (Player_Query_Current_Scene() == kScenePS07
&& ((_vm->_cutContent && Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) < 40)
|| (!_vm->_cutContent && Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) < 35) )
&& !Game_Flag_Query(kFlagPS07KleinInsulted)
) {
// kActorTimerAIScriptCustomTask2 causes the "Klein is annoyed dialogue" to occur after a few seconds
AI_Countdown_Timer_Reset(kActorKlein, kActorTimerAIScriptCustomTask2);
if (_vm->_cutContent) {
// original's 5 seconds is too slow. Reduce it to 2 seconds
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyPreInit);
AI_Countdown_Timer_Start(kActorKlein, kActorTimerAIScriptCustomTask2, 2);
} else {
AI_Countdown_Timer_Start(kActorKlein, kActorTimerAIScriptCustomTask2, 5);
}
Game_Flag_Set(kFlagPS07KleinInsulted);
return true;
}
// The following deals with how Klein recovers from being annoyed at McCoy
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinIsAnnoyedByMcCoyFinal) {
if (Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) > 20
&& Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) < 40
) {
// when insulted, slowly increase friendliness again, until it's at 40 or greater
Actor_Modify_Friendliness_To_Other(kActorKlein, kActorMcCoy, 2);
#if !BLADERUNNER_ORIGINAL_BUGS
if (Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) < 40) {
// if after the increase (+2) it is still lower than 40 then keep being annoyed
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyInit);
return true;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
}
#if BLADERUNNER_ORIGINAL_BUGS
AI_Movement_Track_Flush(kActorKlein);
Actor_Set_Goal_Number(kActorKlein, kGoalKleinDefault);
#else
// don't go to Default if Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) <= 20
// and also reset kFlagPS07KleinInsulted if the friendliness is now above 40
if (Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) >= 40)
{
if (Game_Flag_Query(kFlagPS07KleinInsulted)) {
Game_Flag_Reset(kFlagPS07KleinInsulted);
// don't reset the kFlagPS07KleinInsultedTalk
}
AI_Movement_Track_Flush(kActorKlein);
Actor_Set_Goal_Number(kActorKlein, kGoalKleinDefault);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
return true;
}
return false;
}
void AIScriptKlein::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2) {
#if !BLADERUNNER_ORIGINAL_BUGS
// This timer expiration was buggy; it would play the short dialogue version
// even when the timer expires even if McCoy has left the room and is somewhere else
// The fix is to return when the player is somewhere else
if (Player_Query_Current_Set() != kSetPS07
|| !Actor_Query_Is_In_Current_Set(kActorKlein)
|| !Game_Flag_Query(kFlagPS07KleinInsulted)
) {
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinIsAnnoyedByMcCoyPreInit) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinDefault);
}
return;
}
AI_Movement_Track_Flush(kActorKlein);
#endif
if (!Game_Flag_Query(kFlagPS07KleinInsultedTalk)
#if BLADERUNNER_ORIGINAL_BUGS
// this is redundant now because we return in the added code above if Klein is not insulted
// (and the flag now gets reset when Klein calms down)
&& Game_Flag_Query(kFlagPS07KleinInsulted)
// this is redundant now because we return in the added code above if Klein is not in the current set
&& Actor_Query_Is_In_Current_Set(kActorKlein)
#endif
) {
// Klein is annoyed - full dialogue
Actor_Face_Actor(kActorKlein, kActorMcCoy, true);
Actor_Says(kActorKlein, 10, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 4120, kAnimationModeTalk);
Actor_Says(kActorKlein, 20, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 4125, kAnimationModeTalk);
Game_Flag_Set(kFlagPS07KleinInsultedTalk);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyInit);
#else
if (Actor_Query_Goal_Number(kActorKlein) != kGoalKleinIsAnnoyedByMcCoyInit) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyInit);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
} else {
// Klein is annoyed - short dialogue
Actor_Says(kActorKlein, 10, kAnimationModeTalk);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyInit);
#else
if (Actor_Query_Goal_Number(kActorKlein) != kGoalKleinIsAnnoyedByMcCoyInit) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyInit);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
}
// return true;
}
//return false;
}
void AIScriptKlein::CompletedMovementTrack() {
// Normal behavior
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinMovingInLab01) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinMovingInLab02);
return; // true;
}
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinMovingInLab02) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinMovingInLab01);
return; // true;
}
// Annoyed behavior
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinIsAnnoyedByMcCoyInit) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoy01);
if (_vm->_cutContent) {
return;
}
// NOTE: original was missing return here
}
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinIsAnnoyedByMcCoy01) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoy02);
if (_vm->_cutContent) {
return;
}
// NOTE: original was missing return here
}
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinIsAnnoyedByMcCoy02) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyFinal);
return; // true;
}
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinIsAnnoyedByMcCoyFinal) {
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorKlein, kGoalKleinDefault);
#else
if (Actor_Query_Friendliness_To_Other(kActorKlein, kActorMcCoy) < 40) {
Actor_Set_Goal_Number(kActorKlein, kGoalKleinIsAnnoyedByMcCoyInit);
} else {
if (Game_Flag_Query(kFlagPS07KleinInsulted)) {
Game_Flag_Reset(kFlagPS07KleinInsulted);
// don't reset the kFlagPS07KleinInsultedTalk
}
Actor_Set_Goal_Number(kActorKlein, kGoalKleinDefault);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
return; // true;
}
// return false;
}
void AIScriptKlein::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptKlein::ClickedByPlayer() {
//return false;
}
void AIScriptKlein::EnteredSet(int setId) {
// return false;
}
void AIScriptKlein::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptKlein::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptKlein::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptKlein::ShotAtAndMissed() {
// return false;
}
bool AIScriptKlein::ShotAtAndHit() {
return false;
}
void AIScriptKlein::Retired(int byActorId) {
// return false;
}
int AIScriptKlein::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptKlein::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalKleinMovingInLab01:
AI_Movement_Track_Flush(kActorKlein);
AI_Movement_Track_Append(kActorKlein, 73, Random_Query(3, 20)); // kSetPS07
AI_Movement_Track_Repeat(kActorKlein);
break;
case kGoalKleinMovingInLab02:
AI_Movement_Track_Flush(kActorKlein);
AI_Movement_Track_Append(kActorKlein, 74, Random_Query(10, 20)); // kSetPS07
AI_Movement_Track_Repeat(kActorKlein);
break;
case kGoalKleinGotoLabSpeaker:
AI_Movement_Track_Flush(kActorKlein);
AI_Movement_Track_Append(kActorKlein, 31, 3); // kSetPS07
AI_Movement_Track_Repeat(kActorKlein);
break;
case kGoalKleinIsAnnoyedByMcCoyPreInit:
// aux goal (added)
break;
case kGoalKleinIsAnnoyedByMcCoyInit:
AI_Movement_Track_Flush(kActorKlein);
AI_Movement_Track_Append(kActorKlein, 32, 5); // kSetPS07 (hidden spot)
AI_Movement_Track_Repeat(kActorKlein);
break;
case kGoalKleinIsAnnoyedByMcCoy01:
AI_Movement_Track_Flush(kActorKlein);
if (_vm->_cutContent) {
AI_Movement_Track_Append(kActorKlein, 35, Random_Query(8, 24)); // kSetFreeSlotC
} else {
// this never really gets triggered in the original game
AI_Movement_Track_Append(kActorKlein, 35, 60); // kSetFreeSlotC
}
AI_Movement_Track_Repeat(kActorKlein);
break;
case kGoalKleinIsAnnoyedByMcCoy02:
AI_Movement_Track_Flush(kActorKlein);
AI_Movement_Track_Append(kActorKlein, 32, 5); // kSetPS07 (hidden spot)
AI_Movement_Track_Repeat(kActorKlein);
break;
case kGoalKleinIsAnnoyedByMcCoyFinal:
// Note: Original was missing the kGoalKleinIsAnnoyedByMcCoyFinal case
// so we just "break" for the original behavior
if (_vm->_cutContent) {
AI_Movement_Track_Flush(kActorKlein);
AI_Movement_Track_Append(kActorKlein, 74, Random_Query(10, 20)); // kSetPS07
AI_Movement_Track_Repeat(kActorKlein);
}
break;
case kGoalKleinAwayAtEndOfActThree:
// fall-through
case kGoalKleinAwayAtEndOfActOne:
AI_Movement_Track_Flush(kActorKlein);
Actor_Put_In_Set(kActorKlein, kSetFreeSlotC);
Actor_Set_At_Waypoint(kActorKlein, 35, 0); // kSetFreeSlotC
break;
}
return false;
}
bool AIScriptKlein::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (Actor_Query_Goal_Number(kActorKlein) == kGoalKleinMovingInLab01
|| Actor_Query_Goal_Number(kActorKlein) == kGoalKleinMovingInLab02
) {
*animation = kModelAnimationKleinWorkingOnInstruments;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinWorkingOnInstruments)) {
_animationFrame = 0;
}
} else if (!Game_Flag_Query(kFlagKleinAnimation1)
&& Actor_Query_Goal_Number(kActorKlein) == kGoalKleinGotoLabSpeaker
) {
*animation = kModelAnimationKleinStandingIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinStandingIdle)) {
_animationFrame = 0;
if (Random_Query(1, 10) == 1) {
Game_Flag_Set(kFlagKleinAnimation1);
}
}
} else {
if (Game_Flag_Query(kFlagKleinAnimation3)
&& Actor_Query_Goal_Number(kActorKlein) == kGoalKleinGotoLabSpeaker
) {
--_animationFrame;
if (_animationFrame < 0) {
_animationFrame = 0;
}
} else {
++_animationFrame;
}
*animation = kModelAnimationKleinTalkScratchBackOfHead;
if (_animationFrame <= 9) {
if (Game_Flag_Query(kFlagKleinAnimation3)) {
Game_Flag_Reset(kFlagKleinAnimation3);
}
}
if (_animationFrame == 14) {
if (Random_Query(1, 5) == 1) {
Game_Flag_Set(kFlagKleinAnimation2);
}
}
if (_animationFrame == 15) {
if (Game_Flag_Query(kFlagKleinAnimation2)) {
Game_Flag_Reset(kFlagKleinAnimation2);
Game_Flag_Set(kFlagKleinAnimation3);
}
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinTalkScratchBackOfHead)) {
_animationFrame = 0;
Game_Flag_Reset(kFlagKleinAnimation1);
}
}
break;
case 1:
*animation = kModelAnimationKleinWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinWalking)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationKleinTalkSmallLeftHandMove;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinTalkSmallLeftHandMove)) {
_animationFrame = 0;
}
break;
case 3:
*animation = kModelAnimationKleinTalkRightHandTouchFace;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinTalkRightHandTouchFace)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationKleinTalkSmallLeftHandMove;
}
break;
case 4:
*animation = kModelAnimationKleinTalkWideHandMotion;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinTalkWideHandMotion)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationKleinTalkSmallLeftHandMove;
}
break;
case 5:
*animation = kModelAnimationKleinTalkSuggestOrAsk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinTalkSuggestOrAsk)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationKleinTalkSmallLeftHandMove;
}
break;
case 6:
*animation = kModelAnimationKleinTalkDismissive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinTalkDismissive)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationKleinTalkSmallLeftHandMove;
}
break;
case 7:
*animation = kModelAnimationKleinTalkRaisingBothHands;
++_animationFrame;
if (_animationFrame>= Slice_Animation_Query_Number_Of_Frames(kModelAnimationKleinTalkRaisingBothHands)) {
_animationState = 2;
_animationFrame = 0;
*animation = kModelAnimationKleinTalkSmallLeftHandMove;
}
break;
case 8:
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
break;
default:
// Dummy placeholder, kModelAnimationZubenWalking (399) is a Zuben animation
*animation = kModelAnimationZubenWalking;
debugC(6, kDebugAnimation, "AIScriptKlein::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptKlein::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_animationFrame = 0;
break;
case kAnimationModeWalk:
if (_animationState > 1) {
_animationState = 1;
_animationFrame = 0;
} else if (_animationState == 0) {
_animationState = 8;
_animationStateNext = 1;
_animationNext = kModelAnimationKleinWalking;
}
break;
case kAnimationModeTalk:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 8;
_animationStateNext = 2;
_animationNext = kModelAnimationKleinTalkSmallLeftHandMove;
}
break;
case 12:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 8;
_animationStateNext = 3;
_animationNext = kModelAnimationKleinTalkRightHandTouchFace;
}
break;
case 13:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 8;
_animationStateNext = 4;
_animationNext = kModelAnimationKleinTalkWideHandMotion;
}
break;
case 14:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 8;
_animationStateNext = 5;
_animationNext = kModelAnimationKleinTalkSuggestOrAsk;
}
break;
case 15:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 8;
_animationStateNext = 6;
_animationNext = kModelAnimationKleinTalkDismissive;
}
break;
case 16:
if (_animationState > 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 8;
_animationStateNext = 7;
_animationNext = kModelAnimationKleinTalkRaisingBothHands;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptKlein::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptKlein::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptKlein::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptKlein::ReachedMovementTrackWaypoint(int waypointId) {
if (waypointId == 73 || waypointId == 74) {
Actor_Face_Heading(kActorKlein, 768, false);
}
if (waypointId == 31) {
Actor_Face_Heading(kActorKlein, 216, false);
}
return true;
}
void AIScriptKlein::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptLance::AIScriptLance(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptLance::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptLance::Update() {
return false;
}
void AIScriptLance::TimerExpired(int timer) {
//return false;
}
void AIScriptLance::CompletedMovementTrack() {
//return false;
}
void AIScriptLance::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptLance::ClickedByPlayer() {
//return false;
}
void AIScriptLance::EnteredSet(int setId) {
// return false;
}
void AIScriptLance::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptLance::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptLance::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptLance::ShotAtAndMissed() {
// return false;
}
bool AIScriptLance::ShotAtAndHit() {
return false;
}
void AIScriptLance::Retired(int byActorId) {
// return false;
}
int AIScriptLance::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptLance::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptLance::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptLance::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptLance::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptLance::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptLance::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptLance::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,522 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptLeon::AIScriptLeon(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_mcCoyPositionX = 0.0f;
_mcCoyPositionY = 0.0f;
_mcCoyPositionZ = 0.0f;
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptLeon::Initialize() {
_mcCoyPositionX = 0.0f;
_mcCoyPositionY = 0.0f;
_mcCoyPositionZ = 0.0f;
_resumeIdleAfterFramesetCompletesFlag = false;
_animationStateNext = 0;
_animationNext = 0;
_animationFrame = 0;
_animationState = 0;
}
bool AIScriptLeon::Update() {
int goalNumber = Actor_Query_Goal_Number(kActorLeon);
if (goalNumber == kGoalLeonPrepareTalkToMcCoy) {
Actor_Set_Goal_Number(kActorLeon, kGoalLeonTalkToMcCoy);
return true;
}
if (goalNumber == kGoalLeonApproachMcCoy) {
if (Player_Query_Combat_Mode()) {
Actor_Set_Goal_Number(kActorLeon, kGoalLeonLeave);
return true;
}
if ( Actor_Query_Inch_Distance_From_Actor(kActorLeon, kActorMcCoy) <= 36
&& !Player_Query_Combat_Mode()
) {
Actor_Set_Goal_Number(kActorLeon, kGoalLeonPunchMcCoy);
return true;
}
if (distanceTo(kActorLeon, _mcCoyPositionX, _mcCoyPositionY, _mcCoyPositionZ) > 12.0f) {
Actor_Query_XYZ(kActorMcCoy, &_mcCoyPositionX, &_mcCoyPositionY, &_mcCoyPositionZ);
Async_Actor_Walk_To_XYZ(kActorLeon, _mcCoyPositionX, _mcCoyPositionY, _mcCoyPositionZ, 24, false);
}
return true;
}
return false;
}
void AIScriptLeon::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask0
&& Actor_Query_Goal_Number(kActorLeon) == kGoalLeonLeave
) {
AI_Countdown_Timer_Reset(kActorLeon, kActorTimerAIScriptCustomTask0);
Actor_Set_Goal_Number(kActorLeon, kGoalLeonGone);
}
}
void AIScriptLeon::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorLeon) == kGoalLeonLeave) {
AI_Countdown_Timer_Reset(kActorLeon, kActorTimerAIScriptCustomTask0);
AI_Countdown_Timer_Start(kActorLeon, kActorTimerAIScriptCustomTask0, 8);
//return true;
}
//return false;
}
void AIScriptLeon::ReceivedClue(int clueId, int fromActorId) {}
void AIScriptLeon::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorLeon) == kGoalLeonHoldingDeskClerk) {
Game_Flag_Set(kFlagCT09LeonInterrupted);
Player_Loses_Control();
Actor_Face_Actor(kActorMcCoy, kActorLeon, true);
ADQ_Flush();
Actor_Says(kActorMcCoy, 495, kAnimationModeTalk);
Actor_Set_Goal_Number(kActorLeon, kGoalLeonReleaseDeskClerk);
//return true;
}
//return false;
}
void AIScriptLeon::EnteredSet(int setId) {}
void AIScriptLeon::OtherAgentEnteredThisSet(int otherActorId) {
if (otherActorId == kActorMcCoy
&& Actor_Query_Goal_Number(kActorLeon) == kGoalLeonLeave
) {
AI_Countdown_Timer_Reset(kActorLeon, kActorTimerAIScriptCustomTask0);
AI_Movement_Track_Flush(kActorLeon);
AI_Movement_Track_Append(kActorLeon, 353, 0);
AI_Movement_Track_Repeat(kActorLeon);
//return true;
}
///return false;
}
void AIScriptLeon::OtherAgentExitedThisSet(int otherActorId) {
if (otherActorId == kActorMcCoy
&& Actor_Query_Which_Set_In(kActorLeon) != kSetCT11
) {
AI_Movement_Track_Flush(kActorLeon);
ADQ_Flush();
Actor_Set_Goal_Number(kActorLeon, kGoalLeonGone);
Actor_Set_Goal_Number(kActorDeskClerk, kGoalDeskClerkKnockedOut);
//return true;
}
///return false;
}
void AIScriptLeon::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (otherActorId == kActorMcCoy
&& combatMode == 1
&& Actor_Query_Goal_Number(kActorLeon) == kGoalLeonHoldingDeskClerk
) {
Game_Flag_Set(kFlagCT09LeonInterrupted);
Player_Loses_Control();
Actor_Face_Actor(kActorMcCoy, kActorLeon, true);
Actor_Says(kActorMcCoy, 500, kAnimationModeCombatAim);
Actor_Set_Goal_Number(kActorLeon, kGoalLeonReleaseDeskClerk);
//return true;
}
//return false;
}
void AIScriptLeon::ShotAtAndMissed() {}
bool AIScriptLeon::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorLeon) != kGoalLeonLeave) {
Actor_Set_Goal_Number(kActorLeon, kGoalLeonLeave);
}
return false;
}
void AIScriptLeon::Retired(int byActorId) {}
int AIScriptLeon::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptLeon::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalLeonDefault:
Actor_Put_In_Set(kActorLeon, kSetFreeSlotA);
Actor_Change_Animation_Mode(kActorLeon, kAnimationModeIdle);
return true;
case kGoalLeonHoldingDeskClerk:
Actor_Change_Animation_Mode(kActorDeskClerk, 72);
Actor_Change_Animation_Mode(kActorLeon, 72);
Actor_Put_In_Set(kActorLeon, kSetCT09);
Actor_Set_At_XYZ(kActorLeon, 264.0f, 348.52f, 827.0f, 0);
Actor_Face_Actor(kActorDeskClerk, kActorLeon, true);
ADQ_Add(kActorLeon, 0, 16);
ADQ_Add(kActorDeskClerk, 0, 58);
ADQ_Add(kActorLeon, 10, 15);
ADQ_Add(kActorDeskClerk, 10, 58);
ADQ_Add(kActorLeon, 20, 16);
return true;
case kGoalLeonReleaseDeskClerk:
Actor_Change_Animation_Mode(kActorLeon, 26);
Actor_Change_Animation_Mode(kActorDeskClerk, 26);
return true;
case kGoalLeonTalkToMcCoy:
Actor_Face_Actor(kActorLeon, kActorMcCoy, true);
Player_Set_Combat_Mode(false);
Actor_Says(kActorLeon, 30, 12);
Actor_Face_Actor(kActorMcCoy, kActorLeon, true);
if (Player_Query_Combat_Mode()) {
Player_Set_Combat_Mode(false);
}
Actor_Says(kActorMcCoy, 505, 23);
Actor_Says(kActorLeon, 60, 13);
Player_Gains_Control();
Loop_Actor_Walk_To_XYZ(kActorLeon, 233.0f, 349.0f, 849.0f, 0, false, false, false);
Actor_Face_Actor(kActorLeon, kActorMcCoy, true);
Actor_Face_Actor(kActorMcCoy, kActorLeon, true);
Actor_Says(kActorMcCoy, 515, 18);
Actor_Says_With_Pause(kActorLeon, 70, 0.3f, 12);
Actor_Says(kActorMcCoy, 520, 15);
Actor_Says(kActorLeon, 80, 12);
Loop_Actor_Walk_To_XYZ(kActorLeon, 198.0f, 349.0f, 865.0f, 0, false, false, false);
Actor_Face_Actor(kActorLeon, kActorMcCoy, true);
Actor_Face_Actor(kActorMcCoy, kActorLeon, true);
if (Actor_Clue_Query(kActorMcCoy, kClueWantedPoster)) { // there is no way how to obtain this poster
Actor_Says_With_Pause(kActorMcCoy, 525, 0.2f, 14);
Actor_Says(kActorLeon, 90, 13);
Actor_Says(kActorMcCoy, 530, 16);
Actor_Set_Goal_Number(kActorLeon, kGoalLeonApproachMcCoy);
} else {
Actor_Says_With_Pause(kActorMcCoy, 535, 0.8f, 17);
Actor_Says(kActorLeon, 100, 13);
Actor_Says_With_Pause(kActorMcCoy, 540, 0.0f, 19);
Actor_Says(kActorLeon, 110, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 550, 17);
Actor_Says(kActorMcCoy, 555, 18);
Actor_Says(kActorLeon, 120, 13);
Actor_Says(kActorMcCoy, 560, kAnimationModeTalk);
Actor_Says_With_Pause(kActorLeon, 130, 0.8f, kAnimationModeTalk);
Actor_Face_Current_Camera(kActorMcCoy, true);
Actor_Says(kActorMcCoy, 565, 18);
Actor_Face_Actor(kActorMcCoy, kActorLeon, true);
Actor_Says(kActorLeon, 140, 12);
Actor_Says_With_Pause(kActorMcCoy, 570, 0.0f, 17);
Actor_Says_With_Pause(kActorMcCoy, 575, 1.2f, 13);
Actor_Says(kActorLeon, 150, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 580, kAnimationModeTalk);
Actor_Says(kActorLeon, 160, 13);
Actor_Says(kActorLeon, 170, 12);
Actor_Set_Goal_Number(kActorLeon, kGoalLeonLeave);
}
return true;
case kGoalLeonApproachMcCoy:
return true;
case kGoalLeonPunchMcCoy:
Player_Loses_Control();
Actor_Says(kActorLeon, 40, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 510, kAnimationModeTalk);
Actor_Says(kActorLeon, 50, kAnimationModeTalk);
Actor_Change_Animation_Mode(kActorLeon, kAnimationModeCombatAttack);
return false;
case kGoalLeonLeave:
if (_vm->_cutContent) {
Scene_Exits_Enable();
}
Actor_Force_Stop_Walking(kActorLeon);
AI_Movement_Track_Flush(kActorLeon);
AI_Movement_Track_Append(kActorLeon, 351, 0);
AI_Movement_Track_Append(kActorLeon, 352, 0);
AI_Movement_Track_Repeat(kActorLeon);
return true;
case kGoalLeonGone:
Actor_Put_In_Set(kActorLeon, kSetFreeSlotA);
AI_Movement_Track_Flush(kActorLeon);
return true;
}
return false;
}
bool AIScriptLeon::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelLeonIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelLeonWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonWalking)) {
_animationFrame = 0;
}
break;
case 2:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelLeonIdle;
_animationState = 0;
} else {
*animation = kModelLeonCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonCalmTalk)) {
_animationFrame = 0;
}
}
break;
case 3:
*animation = kModelLeonComplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonComplainTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelLeonCalmTalk;
}
break;
case 4:
*animation = kModelLeonAwkwardTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonAwkwardTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelLeonCalmTalk;
}
break;
case 5:
*animation = kModelLeonDenyTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonDenyTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelLeonCalmTalk;
}
break;
case 6:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
Actor_Change_Animation_Mode(kActorLeon, 72);
*animation = kModelLeonGrabHoldHigh;
} else {
*animation = kModelLeonGrabTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonGrabTalk)) {
_animationFrame = 0;
}
}
break;
case 7:
*animation = kModelLeonGrabAndGutPunchTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonGrabAndGutPunchTalk)) {
_animationFrame = 0;
_animationState = 6;
*animation = kModelLeonGrabTalk;
}
break;
case 8:
*animation = kModelLeonGrabTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonGrabTalk)) {
_animationFrame = 0;
}
break;
case 9:
*animation = kModelLeonGrabLetsGo;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelLeonGrabLetsGo)) {
Actor_Change_Animation_Mode(kActorLeon, kAnimationModeIdle);
*animation = kModelLeonIdle;
_animationFrame = 0;
_animationState = 0;
if (Actor_Query_Goal_Number(kActorLeon) == kGoalLeonReleaseDeskClerk) {
Actor_Set_Goal_Number(kActorLeon, kGoalLeonPrepareTalkToMcCoy);
}
}
break;
case 10:
*animation = kModelLeonPunchAttack;
++_animationFrame;
if (_animationFrame == 6) {
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeDie);
Actor_Retired_Here(kActorMcCoy, 12, 12, true, -1);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelLeonIdle;
_animationFrame = 0;
Actor_Change_Animation_Mode(kActorLeon, kAnimationModeIdle);
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptLeon::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptLeon::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
switch (_animationState) {
case 2:
// fall through
case 3:
// fall through
case 4:
// fall through
case 5:
// fall through
case 6:
// fall through
case 7:
_resumeIdleAfterFramesetCompletesFlag = true;
break;
case 8:
Actor_Change_Animation_Mode(kActorLeon, 72);
break;
default:
_animationState = 0;
_animationFrame = 0;
break;
}
break;
case kAnimationModeWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case kAnimationModeCombatAttack:
_animationState = 10;
_animationFrame = 0;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 16:
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 26:
_animationState = 9;
_animationFrame = 0;
break;
case 72:
if (_animationState != 8) {
_animationState = 8;
_animationFrame = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptLeon::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptLeon::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptLeon::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptLeon::ReachedMovementTrackWaypoint(int waypointId) {
if (waypointId == 353) {
Actor_Set_Goal_Number(kActorLeon, kGoalLeonGone);
}
return true;
}
void AIScriptLeon::FledCombat() {}
float AIScriptLeon::distanceTo(int actorId, float x, float y, float z) {
float actorX, actorY, actorZ;
Actor_Query_XYZ(actorId, &actorX, &actorY, &actorZ);
return sqrt(static_cast<float>((z - actorZ) * (z - actorZ) + (y - actorY) * (y - actorY) + (x - actorX) * (x - actorX)));
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptLockupGuard::AIScriptLockupGuard(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptLockupGuard::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptLockupGuard::Update() {
return false;
}
void AIScriptLockupGuard::TimerExpired(int timer) {
//return false;
}
void AIScriptLockupGuard::CompletedMovementTrack() {
//return false;
}
void AIScriptLockupGuard::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptLockupGuard::ClickedByPlayer() {
//return false;
}
void AIScriptLockupGuard::EnteredSet(int setId) {
// return false;
}
void AIScriptLockupGuard::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptLockupGuard::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptLockupGuard::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptLockupGuard::ShotAtAndMissed() {
// return false;
}
bool AIScriptLockupGuard::ShotAtAndHit() {
return false;
}
void AIScriptLockupGuard::Retired(int byActorId) {
// return false;
}
int AIScriptLockupGuard::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptLockupGuard::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptLockupGuard::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptLockupGuard::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptLockupGuard::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptLockupGuard::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptLockupGuard::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptLockupGuard::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,989 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kLucyStates {
kLucyStateIdle = 0,
kLucyStateWalking = 1,
kLucyStateRunning = 2,
kLucyStateClimbStairsUp = 3,
kLucyStateClimbStairsDown = 4,
kLucyStateGotShotA = 5,
kLucyStateGotShotB = 6,
kLucyStateDie = 7
// TODO fill in the rest of the animationStates
};
AIScriptLucy::AIScriptLucy(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptLucy::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Set_Goal_Number(kActorLucy, kGoalLucyDefault);
}
bool AIScriptLucy::Update() {
float x, y, z;
if (Global_Variable_Query(kVariableChapter) == 3
&& Actor_Query_Goal_Number(kActorLucy) < kGoalLucyMoveAround
) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyMoveAround);
}
if (Actor_Query_Goal_Number(kActorLucy) == kGoalLucyHF04Start
&& Player_Query_Current_Scene() == kSceneHF04
) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04Run1);
}
if (Global_Variable_Query(kVariableChapter) == 4
&& Actor_Query_Goal_Number(kActorLucy) < kGoalLucyStartChapter4
) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyStartChapter4);
}
if (Global_Variable_Query(kVariableChapter) == 4
&& Actor_Query_Goal_Number(kActorLucy) == kGoalLucyGone
&& Actor_Query_Which_Set_In(kActorLucy) != kSetFreeSlotI
) {
if (Actor_Query_Which_Set_In(kActorLucy) != Player_Query_Current_Set()) {
Actor_Put_In_Set(kActorLucy, kSetFreeSlotI);
Actor_Set_At_Waypoint(kActorLucy, 41, 0);
}
}
if (Game_Flag_Query(kFlagMcCoyCapturedByHolloway)
&& Actor_Query_Goal_Number(kActorLucy) == kGoalLucyWillReturnToHF03
) {
Actor_Put_In_Set(kActorLucy, kSetHF03);
Actor_Set_At_Waypoint(kActorLucy, 371, 156);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyReturnToHF03);
}
if ( Actor_Query_Goal_Number(kActorLucy) > 229
&& Actor_Query_Goal_Number(kActorLucy) < 239
&& Actor_Query_Goal_Number(kActorLucy) != kGoalLucyHF04TalkToMcCoy
&& Player_Query_Current_Scene() == kSceneHF04
&& Actor_Query_Which_Set_In(kActorLucy) == kSetHF04
&& !Game_Flag_Query(kFlagMcCoyAttackedLucy)
&& Actor_Query_Inch_Distance_From_Actor(kActorLucy, kActorMcCoy) < 84
&& !Player_Query_Combat_Mode()
&& Actor_Query_Friendliness_To_Other(kActorLucy, kActorMcCoy) > 40
) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04TalkToMcCoy); // TODO how can this be triggered?
}
if (Actor_Query_Goal_Number(kActorLucy) == kGoalLucyHF04WaitForMcCoy1) {
Actor_Query_XYZ(kActorMcCoy, &x, &y, &z);
if (z < -875.0f) {
Game_Flag_Set(kFlagHF04OpenDoors);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04Run3);
}
}
if (Actor_Query_Goal_Number(kActorLucy) == kGoalLucyHF04WaitForMcCoy2) {
Actor_Query_XYZ(kActorMcCoy, &x, &y, &z);
if (x > 350.0f) {
Game_Flag_Set(kFlagHF04CloseDoors);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04Run4);
}
}
return false;
}
void AIScriptLucy::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask0) { // rephrased this to be more expandable (if required)
AI_Countdown_Timer_Reset(kActorLucy, kActorTimerAIScriptCustomTask0);
if (Actor_Query_Goal_Number(kActorLucy) == kGoalLucyGoToHF03) {
if (Player_Query_Current_Scene() == kSceneHF03) {
AI_Countdown_Timer_Start(kActorLucy, kActorTimerAIScriptCustomTask0, 20);
} else {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyMoveAround);
}
}
}
}
void AIScriptLucy::CompletedMovementTrack() {
switch (Actor_Query_Goal_Number(kActorLucy)) {
case kGoalLucyGoToHF03:
if (Game_Flag_Query(kFlagMcCoyCapturedByHolloway)
&& Global_Variable_Query(kVariableHollowayArrest) == 3
) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyReturnToHF03);
return; //true;
}
AI_Countdown_Timer_Reset(kActorLucy, kActorTimerAIScriptCustomTask0);
AI_Countdown_Timer_Start(kActorLucy, kActorTimerAIScriptCustomTask0, 30);
break;
case kGoalLucyHF03RunOutPhase1:
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF03RunOutPhase2);
break;
case kGoalLucyHF03RunOutPhase2:
Game_Flag_Set(kFlagLucyRanAway);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF03RanAway);
break;
case kGoalLucyHF03RunToHF041:
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF03RunToHF042);
break;
case kGoalLucyHF03RunToHF042:
if (Actor_Clue_Query(kActorLucy, kClueMcCoyHelpedLucy)
&& Global_Variable_Query(kVariableHollowayArrest) != 3
) {
Game_Flag_Set(kFlagLucyRanAway);
} else {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04Start);
Game_Flag_Reset(kFlagHF04DoorsClosed);
}
break;
case kGoalLucyHF03RunAwayWithHelp1:
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF03RunAwayWithHelp2);
break;
case kGoalLucyHF03RunAwayWithHelp2:
Actor_Set_Goal_Number(kActorLucy, kGoalLucyWillReturnToHF03);
break;
case kGoalLucyGoToFreeSlotGAG:
// fall through
case kGoalLucyGoToFreeSlotGAHJ:
Actor_Set_Goal_Number(kActorLucy, kGoalLucyMoveAround);
break;
case kGoalLucyHF04Run1:
Game_Flag_Set(kFlagHF04CloseDoors);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04Run2);
break;
case kGoalLucyHF04Run2:
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04WaitForMcCoy1);
break;
case kGoalLucyHF04Run3:
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04WaitForMcCoy2);
break;
case kGoalLucyHF04Run4:
Game_Flag_Set(kFlagLucyRanAway);
Actor_Put_In_Set(kActorLucy, kSetFreeSlotA);
Actor_Set_At_Waypoint(kActorLucy, 33, 0);
Actor_Set_Health(kActorLucy, 30, 30);
if (Global_Variable_Query(kVariableHollowayArrest) == 3) {
Actor_Set_Goal_Number(kActorSteele, kGoalSteeleHF02ConfrontLucy);
}
break;
case kGoalLucyHF04WalkAway:
Game_Flag_Set(kFlagLucyRanAway);
break;
default:
break;
}
return; //false;
}
void AIScriptLucy::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptLucy::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorLucy) == kGoalLucyGone) {
Actor_Face_Actor(kActorMcCoy, kActorLucy, true);
Actor_Says(kActorMcCoy, 8630, kAnimationModeTalk);
}
}
void AIScriptLucy::EnteredSet(int setId) {
// return false;
}
void AIScriptLucy::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptLucy::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptLucy::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptLucy::ShotAtAndMissed() {
checkCombat();
}
bool AIScriptLucy::ShotAtAndHit() {
checkCombat();
return false;
}
void AIScriptLucy::Retired(int byActorId) {
if (byActorId == kActorMcCoy) {
Actor_Modify_Friendliness_To_Other(kActorClovis, kActorMcCoy, -6);
}
#if BLADERUNNER_ORIGINAL_BUGS
#else
if (Actor_Query_In_Set(kActorLucy, kSetKP07)) {
Global_Variable_Decrement(kVariableReplicantsSurvivorsAtMoonbus, 1);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGone);
if (Global_Variable_Query(kVariableReplicantsSurvivorsAtMoonbus) == 0) {
Player_Loses_Control();
Delay(2000);
Player_Set_Combat_Mode(false);
Loop_Actor_Walk_To_XYZ(kActorMcCoy, -12.0f, -41.58f, 72.0f, 0, true, false, false);
Ambient_Sounds_Remove_All_Non_Looping_Sounds(true);
Ambient_Sounds_Remove_All_Looping_Sounds(1u);
Game_Flag_Set(kFlagKP07toKP06);
Game_Flag_Reset(kFlagMcCoyIsHelpingReplicants);
Set_Enter(kSetKP05_KP06, kSceneKP06);
return; //true;
}
}
#endif // BLADERUNNER_ORIGINAL_BUGS
if ((byActorId == kActorSteele
|| byActorId == kActorMcCoy
)
&& Actor_Query_In_Set(kActorSteele, kSetHF06)
&& Actor_Query_In_Set(kActorMcCoy, kSetHF06)
) {
Non_Player_Actor_Combat_Mode_On(kActorSteele, kActorCombatStateUncover, true, kActorMcCoy, 15, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, 0, 0, 100, 25, 300, false);
}
if (Query_Difficulty_Level() != kGameDifficultyEasy
&& byActorId == kActorMcCoy
&& Game_Flag_Query(kFlagLucyIsReplicant)
) {
Global_Variable_Increment(kVariableChinyen, 200);
}
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGone);
}
int AIScriptLucy::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptLucy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == kGoalLucyDefault) {
Actor_Put_In_Set(kActorLucy, kSetFreeSlotA);
return false;
}
switch (newGoalNumber) {
case kGoalLucyMoveAround:
if (Global_Variable_Query(kVariableHollowayArrest) == 3) {
if (Game_Flag_Query(kFlagDektoraRanAway)
&& Game_Flag_Query(kFlagGordoRanAway)
&& Player_Query_Current_Scene() != kSceneHF03
) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGoToHF03);
} else {
if (Random_Query(0, 1) == 1) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGoToFreeSlotGAHJ);
} else {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGoToFreeSlotGAG);
}
}
} else {
int rnd = Random_Query(0, 3);
if (rnd == 0) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGoToFreeSlotGAG);
} else if (rnd == 1) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGoToFreeSlotGAHJ);
} else if (Player_Query_Current_Scene() == kSceneHF03) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGoToFreeSlotGAG);
} else {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGoToHF03);
}
}
break;
case kGoalLucyGoToHF03:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_With_Facing(kActorLucy, 371, 0, 156);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF03RunOutPhase1:
Actor_Set_Immunity_To_Obstacles(kActorLucy, true);
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 377, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF03RunOutPhase2:
Actor_Set_Immunity_To_Obstacles(kActorLucy, false);
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 372, 0);
AI_Movement_Track_Append(kActorLucy, 33, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF03RunToHF041:
Actor_Set_Immunity_To_Obstacles(kActorLucy, true);
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 378, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF03RunToHF042:
Actor_Set_Immunity_To_Obstacles(kActorLucy, false);
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 373, 0);
AI_Movement_Track_Append(kActorLucy, 33, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF03RunAwayWithHelp1:
Actor_Says(kActorLucy, 320, 16);
Actor_Set_Goal_Number(kActorHolloway, kGoalHollowayGoToHF03);
Actor_Set_Immunity_To_Obstacles(kActorLucy, true);
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append(kActorLucy, 378, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF03RunAwayWithHelp2:
Actor_Set_Immunity_To_Obstacles(kActorLucy, false);
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 373, 0);
AI_Movement_Track_Append(kActorLucy, 33, 30);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyGoToFreeSlotGAG:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append(kActorLucy, 39, Random_Query(5, 10));
AI_Movement_Track_Append(kActorLucy, 33, Random_Query(5, 10));
AI_Movement_Track_Append(kActorLucy, 39, Random_Query(5, 10));
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyGoToFreeSlotGAHJ:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append(kActorLucy, 39, Random_Query(5, 15));
AI_Movement_Track_Append(kActorLucy, 33, Random_Query(10, 30));
AI_Movement_Track_Append(kActorLucy, 40, Random_Query(15, 30));
AI_Movement_Track_Append(kActorLucy, 42, Random_Query(10, 20));
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF04Start:
AI_Movement_Track_Flush(kActorLucy);
Actor_Put_In_Set(kActorLucy, kSetHF04);
Actor_Set_At_Waypoint(kActorLucy, 518, 0);
Actor_Set_Targetable(kActorLucy, true);
Actor_Set_Health(kActorLucy, 5, 5);
break;
case kGoalLucyHF04TalkToMcCoy:
Player_Loses_Control();
Actor_Says(kActorMcCoy, 1700, 16);
AI_Movement_Track_Flush(kActorLucy);
Actor_Face_Actor(kActorLucy, kActorMcCoy, true);
Actor_Face_Actor(kActorMcCoy, kActorLucy, true);
Actor_Says(kActorLucy, 350, 13);
Actor_Says(kActorMcCoy, 1705, 13);
Actor_Says(kActorLucy, 360, 13);
Actor_Says(kActorMcCoy, 1710, 13);
if (Global_Variable_Query(kVariableAffectionTowards) == kAffectionTowardsLucy) {
// TODO A cut feature? if this is set lucy will not run into hf04
// Also this dialogue takes place in HF03 script too, but with different animations
Actor_Says(kActorLucy, 940, 13);
Actor_Says(kActorMcCoy, 6780, 12);
Actor_Says(kActorLucy, 950, 12);
Actor_Says(kActorLucy, 960, 14);
Actor_Says(kActorMcCoy, 6785, 13);
Actor_Says(kActorLucy, 970, 16);
Actor_Says(kActorLucy, 980, 13);
if (Game_Flag_Query(kFlagDektoraIsReplicant)) {
Actor_Says(kActorLucy, 990, 15);
}
Actor_Says(kActorMcCoy, 6790, 13);
if (Game_Flag_Query(kFlagDektoraIsReplicant)
&& Game_Flag_Query(kFlagLucyIsReplicant)
) {
Actor_Says(kActorLucy, 1000, 12);
}
Actor_Says(kActorLucy, 1010, 15);
Actor_Says(kActorLucy, 1020, 12);
Actor_Says(kActorMcCoy, 6795, 18);
Actor_Says(kActorLucy, 1030, 15);
Actor_Says(kActorMcCoy, 6800, 16);
Actor_Says(kActorLucy, 1040, 12);
Actor_Says(kActorMcCoy, 6805, 15);
Actor_Says(kActorLucy, 1050, 12);
}
Actor_Says(kActorLucy, 370, 14);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF04WalkAway);
// TODO A bug? Should this be here after Lucy walks away? (It's this way in original)
if (Global_Variable_Query(kVariableHollowayArrest) == 3) {
Actor_Set_Goal_Number(kActorSteele, kGoalSteeleHF02LucyRanAway);
Game_Flag_Set(kFlagLucyRanAway);
}
Player_Gains_Control();
break;
case kGoalLucyHF04Run1:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 519, 0);
AI_Movement_Track_Repeat(kActorLucy);
Actor_Set_Health(kActorLucy, 5, 5);
break;
case kGoalLucyHF04Run2:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 520, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF04Run3:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 521, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF04Run4:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 522, 0);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyHF04WalkAway:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 523, 0);
AI_Movement_Track_Append(kActorLucy, 33, 0);
AI_Movement_Track_Repeat(kActorLucy);
Player_Gains_Control();
Actor_Set_Health(kActorLucy, 30, 30);
break;
case 240: // not used anywhere
if (Global_Variable_Query(kVariableHollowayArrest) == 3) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGone);
Actor_Set_Goal_Number(kActorSteele, kGoalSteeleHF02ConfrontLucy);
} else {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyHF03RanAway);
Game_Flag_Set(kFlagLucyRanAway);
}
break;
case kGoalLucyReturnToHF03:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append(kActorLucy, 372, 0);
AI_Movement_Track_Append_With_Facing(kActorLucy, 371, 0, 156);
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyStartChapter4:
Actor_Put_In_Set(kActorLucy, kSetFreeSlotA);
Actor_Set_At_Waypoint(kActorLucy, 33, 0);
if (Global_Variable_Query(kVariableAffectionTowards) == kAffectionTowardsLucy) {
Actor_Set_Goal_Number(kActorLucy, kGoalLucyUG01Wait);
}
break;
case kGoalLucyUG01Wait:
Actor_Put_In_Set(kActorLucy, kSetUG01);
Actor_Set_At_Waypoint(kActorLucy, 544, 651);
break;
case kGoalLucyUG01VoightKampff:
voightKampffTest();
break;
case kGoalLucyUG01RunAway:
AI_Movement_Track_Flush(kActorLucy);
AI_Movement_Track_Append_Run(kActorLucy, 545, 0);
AI_Movement_Track_Append(kActorLucy, 33, 0); // kSetFreeSlotA
AI_Movement_Track_Repeat(kActorLucy);
break;
case kGoalLucyGone:
Game_Flag_Set(kFlagLucyRanAway);
break;
}
return false;
}
bool AIScriptLucy::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kLucyStateIdle:
*animation = kModelAnimationLucyIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyIdle)) {
_animationFrame = 0;
}
break;
case kLucyStateWalking:
// fall through
case kLucyStateRunning:
// fall through
case kLucyStateClimbStairsUp:
// fall through
case kLucyStateClimbStairsDown:
if (_animationState == kLucyStateWalking) {
*animation = kModelAnimationLucyWalking;
}
if (_animationState == kLucyStateRunning) {
*animation = kModelAnimationLucyRunning;
}
if (_animationState == kLucyStateClimbStairsUp) {
*animation = kModelAnimationLucyClimbStairsUp;
}
if (_animationState == kLucyStateClimbStairsDown) {
*animation = kModelAnimationLucyClimbStairsDown;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case kLucyStateGotShotA:
// fall through
case kLucyStateGotShotB:
if (_animationState == kLucyStateGotShotA) {
*animation = kModelAnimationLucyGotHitBendsForward;
}
if (_animationState == kLucyStateGotShotB) {
*animation = kModelAnimationLucyGotHitBendsBackward;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelAnimationLucyIdle;
_animationFrame = 0;
_animationState = kLucyStateIdle;
Actor_Change_Animation_Mode(kActorLucy, kAnimationModeIdle);
}
break;
case kLucyStateDie:
*animation = kModelAnimationLucyShotDead;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyShotDead) - 1) {
++_animationFrame;
}
break;
case 8:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationLucyIdle;
_animationState = kLucyStateIdle;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
*animation = kModelAnimationLucyCalmShortRightwardsNodTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyCalmShortRightwardsNodTalk)) {
_animationFrame = 0;
}
}
break;
case 9:
// fall through
case 10:
// fall through
case 11:
// fall through
case 12:
// fall through
case 13:
// fall through
case 14:
// fall through
case 15:
// fall through
case 16:
if (_animationState == 9) {
*animation = kModelAnimationLucyComplainingTalk;
}
if (_animationState == 10) {
*animation = kModelAnimationLucyIntenseTalk;
}
if (_animationState == 11) {
*animation = kModelAnimationLucyPointingTalk;
}
if (_animationState == 12) {
*animation = kModelAnimationLucySelfPointingTalk;
}
if (_animationState == 13) {
*animation = kModelAnimationLucyVeryUpsetTalk;
}
if (_animationState == 14) {
*animation = kModelAnimationLucyCalmLongRightwardsNodTalk;
}
if (_animationState == 15) {
*animation = kModelAnimationLucySubtleThrowKissTalk;
}
if (_animationState == 16) {
*animation = kModelAnimationLucyHappyHopTalk;
}
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 8;
*animation = kModelAnimationLucyCalmShortRightwardsNodTalk;
}
break;
case 17:
*animation = kModelAnimationLucyCombatIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyCombatIdle)) {
_animationFrame = 0;
}
break;
case 18:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
_animationState = 17;
_resumeIdleAfterFramesetCompletesFlag = false;
*animation = kModelAnimationLucyCombatIdle;
} else {
*animation = kModelAnimationLucyCombatBlocksUp;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyCombatBlocksUp)) {
_animationFrame = 0;
}
}
break;
case 19:
*animation = kModelAnimationLucyCombatResumeNonCombat;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyCombatResumeNonCombat)) {
*animation = kModelAnimationLucyIdle;
_animationFrame = 0;
_animationState = kLucyStateIdle;
}
break;
case 20:
*animation = kModelAnimationLucyCombatDropsDead;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyCombatDropsDead)) {
_animationFrame = 0;
}
break;
case 21:
*animation = kModelAnimationLucyRemovesNeckletDiesFromExplosion;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationLucyRemovesNeckletDiesFromExplosion)) {
_animationFrame = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptLucy::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptLucy::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState >= 8 && _animationState <= 16) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = kLucyStateIdle;
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = kLucyStateWalking;
_animationFrame = 0;
break;
case kAnimationModeRun:
_animationState = kLucyStateRunning;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 8;
_animationFrame = 0;
break;
case kAnimationModeCombatIdle:
if (_animationState >= 8 && _animationState <= 16) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = kLucyStateIdle;
_animationFrame = 0;
}
break;
case kAnimationModeCombatWalk:
_animationState = kLucyStateWalking;
_animationFrame = 0;
break;
case kAnimationModeCombatRun:
_animationState = kLucyStateRunning;
_animationFrame = 0;
break;
case 12:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 9;
_animationFrame = 0;
break;
case 13:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 10;
_animationFrame = 0;
break;
case 14:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 11;
_animationFrame = 0;
break;
case 15:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 12;
_animationFrame = 0;
break;
case 16:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 13;
_animationFrame = 0;
break;
case 17:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 14;
_animationFrame = 0;
break;
case 18:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 15;
_animationFrame = 0;
break;
case 19:
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 16;
_animationFrame = 0;
break;
case kAnimationModeHit:
if (Random_Query(1, 2) == 1) {
_animationState = kLucyStateGotShotA;
} else {
_animationState = kLucyStateGotShotB;
}
_animationFrame = 0;
break;
case kAnimationModeCombatHit:
if (Random_Query(1, 2) == 1) {
_animationState = kLucyStateGotShotA;
} else {
_animationState = kLucyStateGotShotB;
}
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = kLucyStateDie;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptLucy::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptLucy::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptLucy::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptLucy::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptLucy::FledCombat() {
if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorLucy) == 450
) {
Actor_Put_In_Set(kActorLucy, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorLucy, 39, 0);
Actor_Set_Goal_Number(kActorLucy, kGoalLucyGone);
}
return; //true;
}
void AIScriptLucy::voightKampffTest() {
Player_Loses_Control();
Actor_Face_Actor(kActorMcCoy, kActorLucy, true);
Actor_Says(kActorMcCoy, 6815, 11);
Actor_Face_Actor(kActorLucy, kActorMcCoy, true);
Actor_Says(kActorLucy, 1060, 16);
Actor_Says(kActorLucy, 1070, 17);
Delay(1000);
Actor_Says(kActorLucy, 1080, 14);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorMcCoy, 6820, 16);
#else
// McCoy is interrupted here
Actor_Says_With_Pause(kActorMcCoy, 6820, 0.0f, 16);
#endif // BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorLucy, 1090, 13);
if (!Game_Flag_Query(kFlagDirectorsCut)) {
Actor_Says(kActorMcCoy, 6825, 13);
}
Actor_Says(kActorMcCoy, 6830, 12);
Actor_Says(kActorLucy, 1100, 14);
Actor_Says(kActorMcCoy, 6835, 14);
Actor_Says(kActorLucy, 1110, 15);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorMcCoy, 6840, 13);
#else
// McCoy cuts his sentence short here.
// He is not interrupted, but still we should use Actor_Says_With_Pause 0.0f
Actor_Says_With_Pause(kActorMcCoy, 6840, 0.0f, 13);
#endif // BLADERUNNER_ORIGINAL_BUGS
Delay(1000);
Actor_Says(kActorMcCoy, 6845, 12);
Delay(500);
Actor_Says(kActorMcCoy, 6850, 12);
Actor_Says(kActorLucy, 1120, 14);
Actor_Says(kActorMcCoy, 6855, 13);
Actor_Says(kActorMcCoy, 6860, 13);
Actor_Says(kActorLucy, 1130, 14);
Music_Stop(2u);
Player_Gains_Control();
Voight_Kampff_Activate(kActorLucy, 40);
Player_Loses_Control();
if (Actor_Clue_Query(kActorMcCoy, kClueVKLucyReplicant)) {
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorMcCoy, 6865, 13);
#else
// don't repeat the result, just delay
Delay(250);
#endif // BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorLucy, 1140, 14);
Actor_Says(kActorMcCoy, 6865, 14);
Actor_Says(kActorLucy, 1150, 16);
Actor_Says(kActorMcCoy, 6870, 14);
Delay(500);
Actor_Says(kActorMcCoy, 6875, 13);
Actor_Says(kActorLucy, 1160, 16);
} else {
Actor_Says(kActorMcCoy, 6880, 13);
Actor_Says(kActorLucy, 1170, 13);
Actor_Says(kActorLucy, 1180, 16);
Actor_Says(kActorMcCoy, 6890, 15);
Actor_Says(kActorLucy, 1190, 15);
Actor_Says(kActorLucy, 1200, 17);
Actor_Says(kActorMcCoy, 6885, 13);
Actor_Says(kActorLucy, 1210, 17);
}
Actor_Says(kActorMcCoy, 6895, 15);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorMcCoy, 6900, 11);
#else
// McCoy is interrupted here
Actor_Says_With_Pause(kActorMcCoy, 6900, 0.0f, 11);
#endif // BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorLucy, 1220, 16);
Actor_Says(kActorMcCoy, 6905, 13);
Actor_Says(kActorLucy, 1230, 17);
Actor_Says(kActorMcCoy, 6910, 13);
Delay(2000);
Player_Gains_Control();
Actor_Set_Goal_Number(kActorLucy, kGoalLucyUG01RunAway);
}
void AIScriptLucy::checkCombat() {
Game_Flag_Set(kFlagMcCoyAttackedLucy);
if (Actor_Query_In_Set(kActorLucy, kSetHF01)
&& Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorLucy) != 450
) {
if (Global_Variable_Query(kVariableAffectionTowards) == kAffectionTowardsLucy) {
Global_Variable_Set(kVariableAffectionTowards, kAffectionTowardsNone);
}
Actor_Set_Goal_Number(kActorLucy, 450);
Non_Player_Actor_Combat_Mode_On(kActorLucy, kActorCombatStateIdle, false, kActorMcCoy, 4, kAnimationModeIdle, kAnimationModeWalk, kAnimationModeRun, -1, 0, 0, 10, 300, false);
}
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,490 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptLuther::AIScriptLuther(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptLuther::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorLuther, kSetUG16);
Actor_Set_At_XYZ(kActorLuther, 176.91f, -40.67f, 225.92f, 486);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDefault);
Actor_Set_Targetable(kActorLuther, true);
}
bool AIScriptLuther::Update() {
if ( Actor_Query_Is_In_Current_Set(kActorLuther)
&& Player_Query_Combat_Mode()
&& Global_Variable_Query(kVariableLutherLanceShot) == 0
&& !Game_Flag_Query(kFlagUG16PulledGun)
&& Global_Variable_Query(kVariableChapter) == 4
) {
Actor_Says(kActorMcCoy, 5720, 12); // Just a moment of your time, please.
Actor_Says(kActorLuther, 80, 13); // I am sick and tired of people waving those things around.
Actor_Says(kActorLance, 40, 12); // Just give it up. You got no jurisdiction down here.
Game_Flag_Set(kFlagUG16PulledGun);
return false;
}
if (Actor_Query_Goal_Number(kActorLuther) == kGoalLutherDefault
&& Actor_Query_Goal_Number(kActorLuther) != kGoalLutherDead // A bug? this is redundant
) {
Actor_Set_Goal_Number(kActorLuther, kGoalLutherMoveAround);
return false;
}
if (Actor_Query_Goal_Number(kActorLuther) == kGoalLutherShot) {
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDyingStarted);
ChangeAnimationMode(kAnimationModeDie);
return false;
}
if ( Actor_Query_Goal_Number(kActorLuther) == kGoalLutherDyingStarted
&& !Game_Flag_Query(kFlagUG15LutherLanceStartedDying)
) {
AI_Countdown_Timer_Reset(kActorLuther, kActorTimerAIScriptCustomTask2);
AI_Countdown_Timer_Start(kActorLuther, kActorTimerAIScriptCustomTask2, 5);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDyingWait);
Game_Flag_Set(kFlagUG15LutherLanceStartedDying);
return false;
}
if ( Actor_Query_Goal_Number(kActorLuther) == kGoalLutherDyingCheck
&& Global_Variable_Query(kVariableLutherLanceShot) < 2
&& !Game_Flag_Query(kFlagUG16ComputerOff)
) {
Game_Flag_Set(kFlagUG16ComputerOff);
ChangeAnimationMode(50);
ChangeAnimationMode(kAnimationModeDie);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDie);
Actor_Set_Targetable(kActorLuther, false);
Scene_Loop_Set_Default(5); // UG16MainLoopNoComputerLight
Scene_Loop_Start_Special(kSceneLoopModeOnce, 4, true); // UG16SparkLoop
Ambient_Sounds_Play_Sound(kSfxCOMPDWN4, 50, 0, 0, 99);
Ambient_Sounds_Remove_Looping_Sound(kSfxELECLAB1, 1u);
return false;
}
if ( Actor_Query_Goal_Number(kActorLuther) == kGoalLutherDyingCheck
&& Global_Variable_Query(kVariableLutherLanceShot) > 1
&& !Game_Flag_Query(kFlagUG16ComputerOff)
) {
Actor_Set_Targetable(kActorLuther, false);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDie);
Actor_Set_Targetable(kActorLuther, false);
return false;
}
if (Actor_Query_Goal_Number(kActorLuther) == kGoalLutherDie) {
Game_Flag_Set(kFlagLutherLanceAreDead);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDead);
Actor_Set_Targetable(kActorLuther, false);
return false;
}
return false;
}
void AIScriptLuther::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2) {
AI_Countdown_Timer_Reset(kActorLuther, kActorTimerAIScriptCustomTask2);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDyingCheck);
// return true;
}
// return false;
}
void AIScriptLuther::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorLuther) == kGoalLutherMoveAround) {
Actor_Set_Goal_Number(kActorLuther, kGoalLutherMoveAroundRestart);
// return true;
}
//return false;
}
void AIScriptLuther::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptLuther::ClickedByPlayer() {
//return false;
}
void AIScriptLuther::EnteredSet(int setId) {
// return false;
}
void AIScriptLuther::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptLuther::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptLuther::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptLuther::ShotAtAndMissed() {
// return false;
}
bool AIScriptLuther::ShotAtAndHit() {
#if BLADERUNNER_ORIGINAL_BUGS
#else
if (Actor_Query_In_Set(kActorLuther, kSetKP07)) {
AI_Movement_Track_Flush(kActorLuther);
ChangeAnimationMode(kAnimationModeDie);
Actor_Retired_Here(kActorLuther, 6, 6, true, kActorMcCoy);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherDie);
return false;
}
#endif
if (Actor_Query_Which_Set_In(kActorLuther) == kSetUG16) {
Actor_Set_Health(kActorLuther, 50, 50);
}
Global_Variable_Increment(kVariableLutherLanceShot, 1);
Music_Stop(2u);
if (Global_Variable_Query(kVariableLutherLanceShot) > 0) {
if (!Game_Flag_Query(kFlagLutherLanceIsReplicant)) {
Game_Flag_Set(kFlagNotUsed557);
}
Actor_Set_Goal_Number(kActorLuther, kGoalLutherShot);
return true;
}
return false;
}
void AIScriptLuther::Retired(int byActorId) {
Actor_Set_Goal_Number(kActorLuther, kGoalLutherGone);
#if BLADERUNNER_ORIGINAL_BUGS
#else
if (Actor_Query_In_Set(kActorLuther, kSetKP07)) {
Global_Variable_Decrement(kVariableReplicantsSurvivorsAtMoonbus, 1);
Actor_Set_Goal_Number(kActorLuther, kGoalLutherGone);
if (Global_Variable_Query(kVariableReplicantsSurvivorsAtMoonbus) == 0) {
Player_Loses_Control();
Delay(2000);
Player_Set_Combat_Mode(false);
Loop_Actor_Walk_To_XYZ(kActorMcCoy, -12.0f, -41.58f, 72.0f, 0, true, false, false);
Ambient_Sounds_Remove_All_Non_Looping_Sounds(true);
Ambient_Sounds_Remove_All_Looping_Sounds(1u);
Game_Flag_Set(kFlagKP07toKP06);
Game_Flag_Reset(kFlagMcCoyIsHelpingReplicants);
Set_Enter(kSetKP05_KP06, kSceneKP06);
return; //true;
}
}
#endif // BLADERUNNER_ORIGINAL_BUGS
}
int AIScriptLuther::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptLuther::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalLutherMoveAround:
AI_Movement_Track_Flush(kActorLuther);
AI_Movement_Track_Append(kActorLuther, 39, 20);
AI_Movement_Track_Append_With_Facing(kActorLuther, 368, 120, 486);
AI_Movement_Track_Append(kActorLuther, 40, 10);
AI_Movement_Track_Repeat(kActorLuther);
break;
case kGoalLutherMoveAroundRestart:
Actor_Set_Goal_Number(kActorLuther, kGoalLutherMoveAround);
break;
case kGoalLutherStop:
AI_Movement_Track_Flush(kActorLuther);
break;
case kGoalLutherDead:
Actor_Set_Goal_Number(kActorLuther, kGoalLutherGone);
break;
}
return false;
}
bool AIScriptLuther::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationTwinsSitIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationTwinsSitLancePutsSomethingToTheLeft;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelAnimationTwinsSitIdle;
_animationFrame = 0;
_animationState = 0;
Actor_Change_Animation_Mode(kActorLuther, kAnimationModeIdle);
}
break;
case 2:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationTwinsSitIdle;
_animationState = 0;
} else {
*animation = kModelAnimationTwinsSitLanceShortCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
}
break;
case 3:
*animation = kModelAnimationTwinsSitLanceLongerCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTwinsSitLanceShortCalmTalk;
}
break;
case 4:
*animation = kModelAnimationTwinsSitLutherCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTwinsSitLanceShortCalmTalk;
}
break;
case 5:
*animation = kModelAnimationTwinsSitLutherMoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTwinsSitLanceShortCalmTalk;
}
break;
case 6:
*animation = kModelAnimationTwinsSitLanceMoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTwinsSitLanceShortCalmTalk;
}
break;
case 7:
*animation = kModelAnimationTwinsSitLutherProtestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTwinsSitLanceShortCalmTalk;
}
break;
case 8:
*animation = kModelAnimationTwinsSitLutherGoAheadTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTwinsSitLanceShortCalmTalk;
}
break;
case 9:
*animation = kModelAnimationTwinsSitLutherHitsOrFeedsLance;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
*animation = kModelAnimationTwinsSitIdle;
_animationFrame = 0;
_animationState = 0;
Actor_Change_Animation_Mode(kActorLuther, kAnimationModeIdle);
}
break;
case 10:
*animation = kModelAnimationTwinsSitDropForwards;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
Actor_Change_Animation_Mode(kActorLuther, 50);
*animation = kModelAnimationTwinsSitAlmostDeadLutherPushesButton;
_animationFrame = 0;
}
break;
case 11:
*animation = kModelAnimationTwinsSitAlmostDeadLutherPushesButton;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(*animation) - 1) {
++_animationFrame;
}
break;
case 12:
*animation = kModelAnimationTwinsSitDieCompletely;
if (_animationFrame == 12) {
Ambient_Sounds_Play_Sound(kSfxHEADHIT2, 59, 0, 0, 20);
}
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(*animation) - 1) {
++_animationFrame;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptLuther::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptLuther::ChangeAnimationMode(int mode) {
// these modes are differnent that other actors
switch (mode) {
case 0:
if ((unsigned int)(_animationState - 2) > 6) {
_animationState = 0;
_animationFrame = 0;
} else {
_resumeIdleAfterFramesetCompletesFlag = true;
}
break;
case 3:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 6:
_animationState = 9;
_animationFrame = 0;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 16:
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 17:
_animationState = 8;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 23:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 12;
_animationFrame = 0;
break;
case 50:
_animationState = 11;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptLuther::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptLuther::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptLuther::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptLuther::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptLuther::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMaleAnnouncer::AIScriptMaleAnnouncer(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptMaleAnnouncer::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptMaleAnnouncer::Update() {
return false;
}
void AIScriptMaleAnnouncer::TimerExpired(int timer) {
//return false;
}
void AIScriptMaleAnnouncer::CompletedMovementTrack() {
//return false;
}
void AIScriptMaleAnnouncer::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMaleAnnouncer::ClickedByPlayer() {
//return false;
}
void AIScriptMaleAnnouncer::EnteredSet(int setId) {
// return false;
}
void AIScriptMaleAnnouncer::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMaleAnnouncer::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMaleAnnouncer::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptMaleAnnouncer::ShotAtAndMissed() {
// return false;
}
bool AIScriptMaleAnnouncer::ShotAtAndHit() {
return false;
}
void AIScriptMaleAnnouncer::Retired(int byActorId) {
// return false;
}
int AIScriptMaleAnnouncer::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMaleAnnouncer::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptMaleAnnouncer::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptMaleAnnouncer::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptMaleAnnouncer::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMaleAnnouncer::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMaleAnnouncer::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptMaleAnnouncer::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMarcus::AIScriptMarcus(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptMarcus::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptMarcus::Update() {
return false;
}
void AIScriptMarcus::TimerExpired(int timer) {
//return false;
}
void AIScriptMarcus::CompletedMovementTrack() {
//return false;
}
void AIScriptMarcus::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMarcus::ClickedByPlayer() {
//return false;
}
void AIScriptMarcus::EnteredSet(int setId) {
// return false;
}
void AIScriptMarcus::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMarcus::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMarcus::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptMarcus::ShotAtAndMissed() {
// return false;
}
bool AIScriptMarcus::ShotAtAndHit() {
return false;
}
void AIScriptMarcus::Retired(int byActorId) {
// return false;
}
int AIScriptMarcus::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMarcus::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptMarcus::UpdateAnimation(int *animation, int *frame) {
*animation = kModelAnimationMarcusDead;
*frame = 0;
return true;
}
bool AIScriptMarcus::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptMarcus::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMarcus::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMarcus::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptMarcus::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMia::AIScriptMia(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptMia::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorMia, kSetHF01);
Actor_Set_At_XYZ(kActorMia, 606.77f, -0.01f, -214.3f, 511);
Actor_Set_Goal_Number(kActorMia, 0);
}
bool AIScriptMia::Update() {
if (Global_Variable_Query(kVariableChapter) == 4
&& Actor_Query_Goal_Number(kActorMia) != 300
) {
Actor_Set_Goal_Number(kActorMia, 300);
}
return false;
}
void AIScriptMia::TimerExpired(int timer) {
//return false;
}
void AIScriptMia::CompletedMovementTrack() {
//return false;
}
void AIScriptMia::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMia::ClickedByPlayer() {
//return false;
}
void AIScriptMia::EnteredSet(int setId) {
// return false;
}
void AIScriptMia::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMia::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMia::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptMia::ShotAtAndMissed() {
// return false;
}
bool AIScriptMia::ShotAtAndHit() {
return false;
}
void AIScriptMia::Retired(int byActorId) {
// return false;
}
int AIScriptMia::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMia::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 300) {
Actor_Put_In_Set(kActorMia, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorMia, 40, 0);
}
return false;
}
bool AIScriptMia::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationMiaIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMiaIdle))
_animationFrame = 0;
break;
case 1:
*animation = kModelAnimationMiaGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMiaGestureGive)) {
*animation = kModelAnimationMiaIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 2:
*animation = kModelAnimationMiaHeadNodTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationMiaIdle;
_animationFrame = 0;
_animationState = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
}
break;
case 3:
*animation = kModelAnimationMiaMoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMiaMoreCalmTalk)) {
*animation = kModelAnimationMiaHeadNodTalk;
_animationFrame = 0;
_animationState = 2;
}
break;
case 4:
*animation = kModelAnimationMiaHandsOnWaistTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMiaHandsOnWaistTalk)) {
*animation = kModelAnimationMiaHeadNodTalk;
_animationFrame = 0;
_animationState = 2;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptMia::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptMia::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState >= 2
&& _animationState <= 4
) {
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
_animationFrame = 0;
_animationState = 0;
}
break;
case kAnimationModeTalk:
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 2;
break;
case 12:
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 3;
break;
case 13:
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_animationState = 4;
break;
case 23:
_animationFrame = 0;
_animationState = 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptMia::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptMia::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMia::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMia::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptMia::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,494 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMoraji::AIScriptMoraji(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_var1 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
}
void AIScriptMoraji::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_var1 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiDefault);
}
bool AIScriptMoraji::Update() {
if ( Actor_Query_Goal_Number(kActorMoraji) == kGoalMorajiDefault
&& Player_Query_Current_Scene() == kSceneDR05
&& !Game_Flag_Query(kFlagDR05BombActivated)
) {
AI_Countdown_Timer_Reset(kActorMoraji, kActorTimerAIScriptCustomTask2);
int bombTime = 30; // Original value
if (_vm->_cutContent && Query_Difficulty_Level() == kGameDifficultyEasy)
bombTime += 10; // Extend the bomb timer duration when in Dermo Design (where Moraji is chained)
AI_Countdown_Timer_Start(kActorMoraji, kActorTimerAIScriptCustomTask2, bombTime);
Game_Flag_Set(kFlagDR05BombActivated);
return true;
}
if (Actor_Query_Goal_Number(kActorMoraji) == kGoalMorajiScream) {
Actor_Says(kActorMoraji, 80, 13);
_animationState = 9;
_animationFrame = -1;
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiGetUp);
}
return false;
}
void AIScriptMoraji::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask2) {
AI_Countdown_Timer_Reset(kActorMoraji, kActorTimerAIScriptCustomTask2);
if (Actor_Query_Goal_Number(kActorMoraji) != kGoalMorajiJump
&& Actor_Query_Goal_Number(kActorMoraji) != kGoalMorajiLayDown
&& Actor_Query_Goal_Number(kActorMoraji) != kGoalMorajiPerished
) {
Game_Flag_Set(kFlagDR05BombWillExplode);
}
return; //true;
}
return; //false;
}
void AIScriptMoraji::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorMoraji) == kGoalMorajiRunOut) {
AI_Countdown_Timer_Reset(kActorMoraji, kActorTimerAIScriptCustomTask2);
Game_Flag_Set(kFlagDR05BombWillExplode);
_animationState = 3;
return; //true;
}
return; //false
}
void AIScriptMoraji::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMoraji::ClickedByPlayer() {
//return false;
}
void AIScriptMoraji::EnteredSet(int setId) {
// return false;
}
void AIScriptMoraji::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMoraji::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMoraji::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptMoraji::ShotAtAndMissed() {
// return false;
}
bool AIScriptMoraji::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorMoraji)) {
if (Actor_Query_Goal_Number(kActorMoraji) == kGoalMorajiLayDown) {
Game_Flag_Set(kFlagDR04McCoyShotMoraji);
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiDie);
Actor_Set_Goal_Number(kActorOfficerGrayford, kGoalOfficerGrayfordArrivesToDR04);
return true;
} else {
return false;
}
} else {
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiShot);
return true;
}
}
void AIScriptMoraji::Retired(int byActorId) {
// return false;
}
int AIScriptMoraji::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMoraji::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalMorajiDefault:
Actor_Put_In_Set(kActorMoraji, kSetDR05);
Actor_Set_At_XYZ(kActorMoraji, 50.0f, 0.30f, 35.0f, 414);
Actor_Set_Targetable(kActorMoraji, true);
return false;
case kGoalMorajiShot:
// applies only when shot inside the Dermo Design Lab
Actor_Set_Targetable(kActorMoraji, false);
#if BLADERUNNER_ORIGINAL_BUGS
Sound_Play(kSfxFEMHURT2, 100, 0, 0, 50); // Original code has female scream here (FEMHURT2)
#else
Sound_Play_Speech_Line(kActorMoraji, 9020, 50, 0, 50); // fix: Use Moraji's death SPCHSFX, also lower volume
#endif // BLADERUNNER_ORIGINAL_BUGS
_animationState = 10;
_animationFrame = 0;
Actor_Retired_Here(kActorMoraji, 60, 16, true, -1);
return true;
case kGoalMorajiFreed:
Actor_Set_Targetable(kActorMoraji, false);
_animationState = 8;
_animationFrame = 1;
return true;
case kGoalMorajiRunOut:
_animationState = 3;
_animationFrame = 0;
AI_Movement_Track_Flush(kActorMoraji);
AI_Movement_Track_Append_Run(kActorMoraji, 95, 0);
AI_Movement_Track_Append_Run(kActorMoraji, 96, 0);
AI_Movement_Track_Append_Run(kActorMoraji, 97, 0);
AI_Movement_Track_Append_Run(kActorMoraji, 98, 0);
AI_Movement_Track_Repeat(kActorMoraji);
return true;
case kGoalMorajiJump:
_animationState = 11;
return true;
case kGoalMorajiLayDown:
Actor_Retired_Here(kActorMoraji, 60, 16, false, -1);
Actor_Set_Targetable(kActorMoraji, true);
return true;
case kGoalMorajiDie:
// Added check here to have Moraji death speech SFX
// when shot by McCoy outside the Dermo Design Lab
if (_vm->_cutContent && Game_Flag_Query(kFlagDR04McCoyShotMoraji)) {
// original code used no voice here
Sound_Play_Speech_Line(kActorMoraji, 9020, 50, 0, 50); // Use Moraji's death SPCHSFX, also lower volume
}
_animationFrame = -1;
_animationState = 13;
return true;
case kGoalMorajiDead:
Actor_Set_Targetable(kActorMoraji, false);
_animationState = 14;
Actor_Retired_Here(kActorMoraji, 60, 16, true, -1);
return true;
break;
case kGoalMorajiChooseFate:
if (Player_Query_Current_Scene() == kSceneDR05) {
Game_Flag_Set(kFlagDR05ViewExplosion);
Set_Enter(kSetDR01_DR02_DR04, kSceneDR04);
} else {
if (Actor_Query_In_Set(kActorMoraji, kSetDR05)) {
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiPerished);
} else {
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiJump);
}
Game_Flag_Set(kFlagDR05JustExploded);
}
return true;
case kGoalMorajiPerished:
AI_Movement_Track_Flush(kActorMoraji);
AI_Movement_Track_Append(kActorMoraji, 41, 0);
AI_Movement_Track_Repeat(kActorMoraji);
return true;
}
return false;
}
bool AIScriptMoraji::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationMorajiCuffedIdle;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
_animationFrame += _var1;
if (Random_Query(0, 10) == 0) {
_var1 = -_var1;
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(*animation) - 1;
}
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 1);
}
break;
case 1:
_animationFrame = 0;
*animation = _animationNext;
_animationState = _animationStateNext;
break;
case 2:
// Dummy placeholder, kModelAnimationIzoWalking (290) is an Izo animation
*animation = kModelAnimationIzoWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationIzoWalking))
_animationFrame = 0;
break;
case 3:
*animation = kModelAnimationMorajiRunning;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiRunning))
_animationFrame = 0;
break;
case 4:
break;
case 5:
*animation = kModelAnimationMorajiCuffedFastTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiCuffedFastTalk)) {
_animationFrame = 0;
_animationState = Random_Query(0, 2) + 5;
}
break;
case 6:
*animation = kModelAnimationMorajiCuffedMoreFastTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiCuffedMoreFastTalk)) {
_animationFrame = 0;
_animationState = 5;
*animation = kModelAnimationMorajiCuffedMoreFastTalk;
}
break;
case 7:
*animation = kModelAnimationMorajiCuffedPointingTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiCuffedPointingTalk)) {
_animationFrame = 0;
_animationState = 5;
*animation = kModelAnimationMorajiCuffedPointingTalk;
}
break;
case 8:
*animation = kModelAnimationMorajiCuffedSomethingExplodingToHisLeft;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiCuffedSomethingExplodingToHisLeft)) {
_animationFrame = 0;
_animationState = 0;
*animation = kModelAnimationMorajiCuffedIdle;
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiScream);
}
if (_animationFrame == 6) {
Ambient_Sounds_Play_Sound(kSfxCHAINBRK, 69, 0, 0, 20);
}
break;
case 9:
*animation = kModelAnimationMorajiSittingGetsUp;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiSittingGetsUp)) {
_animationFrame = 0;
_animationState = 3;
*animation = kModelAnimationMorajiRunning;
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiRunOut);
}
break;
case 10:
*animation = kModelAnimationMorajiCuffedShotDead;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiCuffedShotDead) - 1) {
++_animationFrame;
}
break;
case 11:
*animation = kModelAnimationMorajiRunningDivesForward;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiRunningDivesForward)) {
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiLayDown);
_animationFrame = 0;
_animationState = 12;
*animation = kModelAnimationMorajiLayingForwardTalk;
}
break;
case 12:
*animation = kModelAnimationMorajiLayingForwardTalk;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
_animationFrame += _var1;
if (!Random_Query(0, 5)) {
_var1 = -_var1;
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(*animation) - 1;
}
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 2);
}
break;
case 13:
*animation = kModelAnimationMorajiLayingForwardDies;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiLayingForwardDies) - 1) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(*animation) - 1;
Actor_Set_Goal_Number(kActorMoraji, kGoalMorajiDead);
}
break;
case 14:
*animation = kModelAnimationMorajiLayingForwardDies;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMorajiLayingForwardDies) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptMoraji::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptMoraji::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState != 12
&& Actor_Query_Goal_Number(kActorMoraji) != 11
) {
_animationState = 0;
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = 2;
_animationFrame = 0;
break;
case kAnimationModeRun:
if (_animationState == 0) {
_animationState = 1;
_animationStateNext = 3;
_animationNext = kModelAnimationMorajiRunning;
} else if (_animationState != 3) {
_animationState = 3;
_animationFrame = 0;
}
break;
case 3:
if (_animationState != 12) {
if (_animationState == 0) {
_animationState = 1;
_animationStateNext = 5;
_animationNext = 734;
} else {
_animationState = 5;
_animationFrame = 0;
}
}
break;
case 12:
if (_animationState == 0) {
_animationState = 1;
_animationStateNext = 6;
_animationNext = kModelAnimationMorajiCuffedMoreFastTalk;
} else {
_animationState = 6;
_animationFrame = 0;
}
break;
case 13:
if (_animationState == 0) {
_animationState = 1;
_animationStateNext = 7;
_animationNext = kModelAnimationMorajiCuffedPointingTalk;
} else {
_animationState = 7;
_animationFrame = 0;
}
break;
case kAnimationModeDie:
_animationState = 13;
_animationFrame = -1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptMoraji::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptMoraji::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMoraji::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMoraji::ReachedMovementTrackWaypoint(int waypointId) {
if (waypointId == 96)
AI_Countdown_Timer_Reset(kActorMoraji, kActorTimerAIScriptCustomTask2);
return true;
}
void AIScriptMoraji::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,273 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMurray::AIScriptMurray(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptMurray::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorMurray, kSetHF01);
Actor_Set_At_XYZ(kActorMurray, 566.07f, -0.01f, -205.43f, 271);
Actor_Set_Goal_Number(kActorMurray, 0);
}
bool AIScriptMurray::Update() {
if (Global_Variable_Query(kVariableChapter) == 4
&& Actor_Query_Goal_Number(kActorMurray) != 300
) {
Actor_Set_Goal_Number(kActorMurray, 300);
}
if (Player_Query_Current_Set() != kSetHF01) {
return true;
}
if ( Actor_Query_In_Set(kActorMcCoy, kSetHF01)
&& Actor_Query_In_Set(kActorMurray, kSetHF01)
&& Actor_Query_Inch_Distance_From_Actor(kActorMcCoy, kActorMurray) < 48
&& !Game_Flag_Query(kFlagHF01MurrayMiaIntro)
) {
Actor_Set_Goal_Number(kActorMurray, 1);
return true;
}
return false;
}
void AIScriptMurray::TimerExpired(int timer) {
//return false;
}
void AIScriptMurray::CompletedMovementTrack() {
//return false;
}
void AIScriptMurray::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMurray::ClickedByPlayer() {
//return false;
}
void AIScriptMurray::EnteredSet(int setId) {
// return false;
}
void AIScriptMurray::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMurray::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMurray::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptMurray::ShotAtAndMissed() {
// return false;
}
bool AIScriptMurray::ShotAtAndHit() {
return false;
}
void AIScriptMurray::Retired(int byActorId) {
// return false;
}
int AIScriptMurray::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMurray::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 300) {
Actor_Put_In_Set(kActorMurray, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorMurray, 40, 0);
}
return false;
}
bool AIScriptMurray::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationMurrayIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMurrayIdle))
_animationFrame = 0;
break;
case 1:
*animation = kModelAnimationMurrayCalmTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
_animationState = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMurrayCalmTalk))
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationMurrayMoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMurrayMoreCalmTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationMurrayCalmTalk;
}
break;
case 3:
*animation = kModelAnimationMurrayExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMurrayExplainTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationMurrayCalmTalk;
}
break;
case 4:
*animation = kModelAnimationMurrayMoreExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMurrayMoreExplainTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationMurrayCalmTalk;
}
break;
case 5:
*animation = kModelAnimationMurrayCautionTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMurrayCautionTalk)) {
_animationFrame = 0;
_animationState = 1;
*animation = kModelAnimationMurrayCalmTalk;
}
break;
case 6:
*animation = kModelAnimationMurrayGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMurrayGestureGive)) {
*animation = kModelAnimationMurrayIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptMurray::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptMurray::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState > 0 && _animationState <= 5) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case kAnimationModeTalk:
_animationState = 1;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
default:
debugC(6, kDebugAnimation, "AIScriptMurray::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptMurray::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMurray::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMurray::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptMurray::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,628 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMutant1::AIScriptMutant1(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptMutant1::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorMutant1, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorMutant1, 39, 0);
Actor_Set_Goal_Number(kActorMutant1, 400);
}
bool AIScriptMutant1::Update() {
if (Global_Variable_Query(kVariableChapter) == 4) {
switch (Actor_Query_Goal_Number(kActorMutant1)) {
case 400:
if (!Game_Flag_Query(kFlagMutantsActive)
&& Game_Flag_Query(kFlagUG06Chapter4Started)
) {
Actor_Set_Goal_Number(kActorMutant1, 401);
Actor_Set_Goal_Number(kActorMutant2, 401);
Actor_Set_Goal_Number(kActorMutant3, 401);
Actor_Set_Targetable(kActorMutant1, true);
Actor_Set_Targetable(kActorMutant2, true);
Actor_Set_Targetable(kActorMutant3, true);
Game_Flag_Set(kFlagMutantsActive);
}
break;
case 401:
if (Actor_Query_Which_Set_In(kActorMutant1) == Player_Query_Current_Set()
&& (Actor_Query_Friendliness_To_Other(kActorMutant1, kActorMcCoy) < 30
|| Actor_Query_Combat_Aggressiveness(kActorMutant1) >= 60
)
) {
Actor_Set_Goal_Number(kActorMutant1, 410);
}
break;
case 404:
if (!Game_Flag_Query(kFlagMutantsPaused)) {
Actor_Set_Goal_Number(kActorMutant1, 403);
}
break;
case 410:
if (Actor_Query_Which_Set_In(kActorMutant1) != Player_Query_Current_Set()) {
Non_Player_Actor_Combat_Mode_Off(kActorMutant1);
Actor_Set_Goal_Number(kActorMutant1, 403);
}
break;
case 599:
if (Actor_Query_Which_Set_In(kActorMutant1) != Player_Query_Current_Set()) {
Actor_Set_Goal_Number(kActorMutant1, 411);
}
break;
}
if (Game_Flag_Query(kFlagMutantsPaused)
&& Actor_Query_Goal_Number(kActorMutant1) != 599
) {
Actor_Set_Goal_Number(kActorMutant1, 404);
}
} else if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorMutant1) != 590
) {
if (Actor_Query_Which_Set_In(kActorMutant1) != Player_Query_Current_Set()) {
Actor_Set_Goal_Number(kActorMutant1, 590);
}
}
return false;
}
void AIScriptMutant1::TimerExpired(int timer) {
//return false;
}
void AIScriptMutant1::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorMutant1) == 401) {
Actor_Set_Goal_Number(kActorMutant1, 403);
}
}
void AIScriptMutant1::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMutant1::ClickedByPlayer() {
//return false;
}
void AIScriptMutant1::EnteredSet(int setId) {
// return false;
}
void AIScriptMutant1::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMutant1::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMutant1::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (Actor_Query_Which_Set_In(kActorMutant1) == Player_Query_Current_Set()
&& Actor_Query_Goal_Number(kActorMutant1) != 599
) {
if (otherActorId == kActorMcCoy) {
if (combatMode) {
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
} else {
Actor_Modify_Combat_Aggressiveness(kActorMutant1, -10);
}
} else if (otherActorId == kActorFreeSlotA
|| otherActorId == kActorMutant2
|| otherActorId == kActorMutant3
) {
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
} else {
Actor_Modify_Combat_Aggressiveness(kActorMutant1, -10);
}
}
}
void AIScriptMutant1::ShotAtAndMissed() {
if (Actor_Query_Goal_Number(kActorMutant1) != 410) {
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, -10);
}
}
bool AIScriptMutant1::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorMutant1) != 410) {
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 15);
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, -15);
}
return false;
}
void AIScriptMutant1::Retired(int byActorId) {
Actor_Set_Goal_Number(kActorMutant1, 599);
}
int AIScriptMutant1::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMutant1::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 400:
AI_Movement_Track_Flush(kActorMutant1);
AI_Movement_Track_Append(kActorMutant1, 39, 0);
AI_Movement_Track_Repeat(kActorMutant1);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant1, 70);
Actor_Set_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 20);
}
return true;
case 401:
Actor_Set_Targetable(kActorMutant1, true);
AI_Movement_Track_Flush(kActorMutant1);
AI_Movement_Track_Append(kActorMutant1, 39, 0);
switch (Random_Query(1, 8)) {
case 1:
AI_Movement_Track_Append(kActorMutant1, 182, 0);
AI_Movement_Track_Append(kActorMutant1, 183, 2);
AI_Movement_Track_Append(kActorMutant1, 184, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 2:
AI_Movement_Track_Append(kActorMutant1, 296, 0);
AI_Movement_Track_Append(kActorMutant1, 297, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 3:
AI_Movement_Track_Append(kActorMutant1, 176, 0);
AI_Movement_Track_Append(kActorMutant1, 177, 0);
AI_Movement_Track_Append(kActorMutant1, 178, 2);
AI_Movement_Track_Append(kActorMutant1, 177, 0);
AI_Movement_Track_Append(kActorMutant1, 176, 1);
AI_Movement_Track_Append(kActorMutant1, 39, 45);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 4:
AI_Movement_Track_Append(kActorMutant1, 298, 0);
AI_Movement_Track_Append(kActorMutant1, 300, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 5:
AI_Movement_Track_Append(kActorMutant1, 301, 0);
AI_Movement_Track_Append(kActorMutant1, 302, 2);
AI_Movement_Track_Append(kActorMutant1, 303, 0);
AI_Movement_Track_Append(kActorMutant1, 304, 0);
AI_Movement_Track_Append(kActorMutant1, 305, 0);
AI_Movement_Track_Append(kActorMutant1, 304, 0);
AI_Movement_Track_Append(kActorMutant1, 306, 0);
AI_Movement_Track_Append(kActorMutant1, 39, 60);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 6:
AI_Movement_Track_Append(kActorMutant1, 307, 0);
AI_Movement_Track_Append(kActorMutant1, 308, 0);
AI_Movement_Track_Append(kActorMutant1, 309, 1);
AI_Movement_Track_Append(kActorMutant1, 310, 3);
AI_Movement_Track_Append(kActorMutant1, 311, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 7:
switch (Random_Query(1, 5)) {
case 1:
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 534, 2);
AI_Movement_Track_Append(kActorMutant1, 535, 3);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 2:
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 535, 2);
AI_Movement_Track_Append(kActorMutant1, 534, 3);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 3:
AI_Movement_Track_Append(kActorMutant1, 536, 0);
AI_Movement_Track_Append(kActorMutant1, 537, 0);
AI_Movement_Track_Append(kActorMutant1, 538, 2);
AI_Movement_Track_Append(kActorMutant1, 537, 0);
AI_Movement_Track_Append(kActorMutant1, 536, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 4:
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 534, 3);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
case 5:
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 535, 1);
AI_Movement_Track_Append(kActorMutant1, 533, 0);
AI_Movement_Track_Append(kActorMutant1, 532, 0);
AI_Movement_Track_Repeat(kActorMutant1);
break;
default:
return true;
}
break;
case 8:
if (Game_Flag_Query(kFlagUG07Empty)) {
AI_Movement_Track_Append(kActorMutant1, 418, 0);
AI_Movement_Track_Append(kActorMutant1, 417, 0);
AI_Movement_Track_Append(kActorMutant1, 539, 0);
AI_Movement_Track_Repeat(kActorMutant1);
} else {
Actor_Set_Goal_Number(kActorMutant1, 403);
}
break;
default:
AI_Movement_Track_Append(kActorMutant1, 39, 60);
AI_Movement_Track_Repeat(kActorMutant1);
break;
}
return true;
case 403:
Actor_Set_Targetable(kActorMutant1, false);
Actor_Set_Goal_Number(kActorMutant1, 401);
return true;
case 404:
AI_Movement_Track_Flush(kActorMutant1);
AI_Movement_Track_Append(kActorMutant1, 39, 0);
AI_Movement_Track_Repeat(kActorMutant1);
return true;
case 410:
switch (Actor_Query_Which_Set_In(kActorMutant1)) {
case kSetUG01:
Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 11, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG04:
// fall through
case kSetUG05:
// fall through
case kSetUG06:
Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 10, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG07:
Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 12, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG10:
// fall through
case kSetUG12:
// fall through
case kSetUG14:
Non_Player_Actor_Combat_Mode_On(kActorMutant1, kActorCombatStateIdle, false, kActorMcCoy, 14, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
}
return true;
case 411:
AI_Movement_Track_Flush(kActorMutant1);
Actor_Set_Intelligence(kActorMutant1, 40);
Actor_Set_Health(kActorMutant1, 10 * Query_Difficulty_Level() + 30, 10 * Query_Difficulty_Level() + 30);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant1, 70);
Actor_Set_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 20);
} else {
Actor_Set_Combat_Aggressiveness(kActorMutant1, 40);
Actor_Set_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 45);
}
// code repeated also in case 599 which precedes this one
// redundant?
// results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, -10);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 15);
Actor_Set_Goal_Number(kActorMutant1, 403);
return true;
case 590:
AI_Movement_Track_Flush(kActorMutant1);
AI_Movement_Track_Append(kActorMutant1, 39, 100);
AI_Movement_Track_Repeat(kActorMutant1);
return true;
case 599:
AI_Movement_Track_Flush(kActorMutant1);
Actor_Change_Animation_Mode(kActorMutant1, kAnimationModeDie);
// results in additional reduction in friendlinees and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, -10);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 15);
return true;
default:
break;
}
return false;
}
bool AIScriptMutant1::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationMutant1Idle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1Idle)) {
_animationFrame = 0;
}
break;
case 1:
// fall through
case 2:
*animation = kModelAnimationMutant1Walking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1Walking)) {
_animationFrame = 0;
}
break;
case 3:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationMutant1Idle;
_animationState = 0;
} else {
*animation = kModelAnimationMutant1MoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1MoreCalmTalk)) {
_animationFrame = 0;
}
}
break;
case 4:
*animation = kModelAnimationMutant1MoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1MoreCalmTalk)) {
_animationFrame = 0;
_animationState = 3;
*animation = kModelAnimationMutant1MoreCalmTalk;
}
break;
case 5:
*animation = kModelAnimationMutant1YellOrHurt;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1YellOrHurt)) {
_animationFrame = 0;
_animationState = 3;
*animation = kModelAnimationMutant1MoreCalmTalk;
}
break;
case 6:
*animation = kModelAnimationMutant1MeleeAttack;
++_animationFrame;
if (_animationFrame == 5) {
int snd;
if (Random_Query(1, 2) == 1) {
snd = 9010;
} else {
snd = 9015;
}
Sound_Play_Speech_Line(kActorMutant1, snd, 75, 0, 99);
}
if (_animationFrame == 9) {
Actor_Combat_AI_Hit_Attempt(kActorMutant1);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1MeleeAttack)) {
Actor_Change_Animation_Mode(kActorMutant1, kAnimationModeIdle);
}
break;
case 7:
*animation = kModelAnimationMutant1Jump;
++_animationFrame;
if (_animationFrame == 1) {
Ambient_Sounds_Play_Sound(kSfxHURT1M1, 99, 0, 0, 25);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1Jump)) {
Actor_Change_Animation_Mode(kActorMutant1, kAnimationModeIdle);
}
break;
case 8:
*animation = kModelAnimationMutant1ShotDead;
++_animationFrame;
if (_animationFrame == 1) {
Sound_Play(kSfxYELL1M1, 100, 0, 0, 50);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1ShotDead)) {
Actor_Change_Animation_Mode(kActorMutant1, 88);
}
break;
case 9:
*animation = kModelAnimationMutant1ShotDead;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1ShotDead) - 1;
break;
case 10:
*animation = kModelAnimationMutant1Jump;
++_animationFrame;
if (_animationFrame == 9) {
Sound_Play(kSfxHURT1M1, 100, 0, 0, 50);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1Jump)) {
Actor_Change_Animation_Mode(kActorMutant1, kAnimationModeIdle);
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptMutant1::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptMutant1::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState >= 3 && _animationState <= 5) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
// fall through
case kAnimationModeCombatWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeRun:
// fall through
case kAnimationModeCombatRun:
_animationState = 2;
_animationFrame = 0;
break;
case 3:
// fall through
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 4:
if (_animationState >= 3 && _animationState <= 5) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case 6:
_animationState = 6;
_animationFrame = 0;
break;
case 13:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 21:
// fall through
case 22:
_animationState = 10;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 8;
_animationFrame = 0;
break;
case 88:
_animationState = 9;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant1ShotDead) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptMutant1::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptMutant1::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMutant1::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMutant1::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptMutant1::FledCombat() {
Actor_Set_Goal_Number(kActorMutant1, 403);
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,611 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMutant2::AIScriptMutant2(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
_var1 = 1;
}
void AIScriptMutant2::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
_var1 = 1;
Actor_Put_In_Set(kActorMutant2, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorMutant2, 39, 0);
Actor_Set_Goal_Number(kActorMutant2, 400);
}
bool AIScriptMutant2::Update() {
if (Global_Variable_Query(kVariableChapter) == 4) {
switch (Actor_Query_Goal_Number(kActorMutant2)) {
case 401:
if (Actor_Query_Which_Set_In(kActorMutant2) == Player_Query_Current_Set()
&& (Actor_Query_Friendliness_To_Other(kActorMutant2, kActorMcCoy) < 20
|| Actor_Query_Combat_Aggressiveness(kActorMutant2) >= 60
)
) {
Actor_Set_Goal_Number(kActorMutant2, 410);
}
break;
case 404:
if (!Game_Flag_Query(kFlagMutantsPaused)) {
Actor_Set_Goal_Number(kActorMutant2, 403);
}
break;
case 410:
if (Actor_Query_Which_Set_In(kActorMutant2) != Player_Query_Current_Set()) {
Non_Player_Actor_Combat_Mode_Off(kActorMutant2);
Actor_Set_Goal_Number(kActorMutant2, 403);
}
break;
case 599:
if (Actor_Query_Which_Set_In(kActorMutant2) != Player_Query_Current_Set()) {
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorMutant2, 403);
#else
// intermediate goal to set new Health (revive for reuse)
Actor_Set_Goal_Number(kActorMutant2, 411);
#endif // BLADERUNNER_ORIGINAL_BUGS
}
break;
}
if (Game_Flag_Query(kFlagMutantsPaused)
&& Actor_Query_Goal_Number(kActorMutant2) != 599
) {
Actor_Set_Goal_Number(kActorMutant2, 404);
}
} else if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorMutant2) != 590
) {
if (Actor_Query_Which_Set_In(kActorMutant2) != Player_Query_Current_Set()) {
Actor_Set_Goal_Number(kActorMutant2, 590);
}
}
return false;
}
void AIScriptMutant2::TimerExpired(int timer) {
//return false;
}
void AIScriptMutant2::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorMutant2) == 401)
Actor_Set_Goal_Number(kActorMutant2, 403);
}
void AIScriptMutant2::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMutant2::ClickedByPlayer() {
//return false;
}
void AIScriptMutant2::EnteredSet(int setId) {
// return false;
}
void AIScriptMutant2::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMutant2::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMutant2::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (Actor_Query_Which_Set_In(kActorMutant2) == Player_Query_Current_Set()
&& Actor_Query_Goal_Number(kActorMutant2) != 599
) {
if (otherActorId == kActorMcCoy) {
if (combatMode) {
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
} else {
Actor_Modify_Combat_Aggressiveness(kActorMutant2, -10);
}
} else if (otherActorId == kActorFreeSlotA
|| otherActorId == kActorMutant1
|| otherActorId == kActorMutant3
) {
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 5);
} else {
Actor_Modify_Combat_Aggressiveness(kActorMutant2, -10);
}
}
}
void AIScriptMutant2::ShotAtAndMissed() {
if (Actor_Query_Goal_Number(kActorMutant2) != 410) {
Actor_Modify_Combat_Aggressiveness(kActorMutant2, -5);
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, -5);
}
}
bool AIScriptMutant2::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorMutant2) != 410) {
Actor_Modify_Combat_Aggressiveness(kActorMutant2, -10);
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, -10);
}
return false;
}
void AIScriptMutant2::Retired(int byActorId) {
Actor_Set_Goal_Number(kActorMutant2, 599);
}
int AIScriptMutant2::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMutant2::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 400:
AI_Movement_Track_Flush(kActorMutant2);
AI_Movement_Track_Append(kActorMutant2, 39, 0);
AI_Movement_Track_Repeat(kActorMutant2);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant2, 60);
Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 30);
}
return true;
case 401:
Actor_Set_Targetable(kActorMutant2, true);
AI_Movement_Track_Flush(kActorMutant2);
AI_Movement_Track_Append(kActorMutant2, 39, 0);
switch (Random_Query(1, 8)) {
case 1:
AI_Movement_Track_Append(kActorMutant2, 182, 0);
AI_Movement_Track_Append(kActorMutant2, 183, 2);
AI_Movement_Track_Append(kActorMutant2, 184, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 2:
AI_Movement_Track_Append(kActorMutant2, 296, 0);
AI_Movement_Track_Append(kActorMutant2, 297, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 3:
AI_Movement_Track_Append(kActorMutant2, 176, 0);
AI_Movement_Track_Append(kActorMutant2, 177, 0);
AI_Movement_Track_Append(kActorMutant2, 178, 2);
AI_Movement_Track_Append(kActorMutant2, 177, 0);
AI_Movement_Track_Append(kActorMutant2, 176, 1);
AI_Movement_Track_Append(kActorMutant2, 39, 45);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 4:
AI_Movement_Track_Append(kActorMutant2, 298, 0);
AI_Movement_Track_Append(kActorMutant2, 300, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 5:
AI_Movement_Track_Append(kActorMutant2, 301, 0);
AI_Movement_Track_Append(kActorMutant2, 302, 2);
AI_Movement_Track_Append(kActorMutant2, 303, 0);
AI_Movement_Track_Append(kActorMutant2, 304, 0);
AI_Movement_Track_Append(kActorMutant2, 305, 0);
AI_Movement_Track_Append(kActorMutant2, 304, 0);
AI_Movement_Track_Append(kActorMutant2, 306, 5);
AI_Movement_Track_Append(kActorMutant2, 39, 40);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 6:
AI_Movement_Track_Append(kActorMutant2, 307, 0);
AI_Movement_Track_Append(kActorMutant2, 308, 0);
AI_Movement_Track_Append(kActorMutant2, 309, 1);
AI_Movement_Track_Append(kActorMutant2, 310, 2);
AI_Movement_Track_Append(kActorMutant2, 311, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 7:
switch (Random_Query(1, 3)) { // eeh? bug?
case 1:
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 534, 1);
AI_Movement_Track_Append(kActorMutant2, 535, 1);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 2:
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 535, 2);
AI_Movement_Track_Append(kActorMutant2, 534, 1);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 3:
AI_Movement_Track_Append(kActorMutant2, 536, 0);
AI_Movement_Track_Append(kActorMutant2, 537, 0);
AI_Movement_Track_Append(kActorMutant2, 538, 2);
AI_Movement_Track_Append(kActorMutant2, 537, 0);
AI_Movement_Track_Append(kActorMutant2, 536, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 4:
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 534, 3);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
case 5:
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 535, 1);
AI_Movement_Track_Append(kActorMutant2, 533, 0);
AI_Movement_Track_Append(kActorMutant2, 532, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
default:
return true;
}
break;
case 8:
AI_Movement_Track_Append(kActorMutant2, 176, 0);
AI_Movement_Track_Append(kActorMutant2, 177, 0);
AI_Movement_Track_Append(kActorMutant2, 176, 0);
AI_Movement_Track_Repeat(kActorMutant2);
break;
default:
AI_Movement_Track_Append(kActorMutant2, 39, 60);
AI_Movement_Track_Repeat(kActorMutant2);
break;
}
return true;
case 403:
Actor_Set_Targetable(kActorMutant2, false);
Actor_Set_Goal_Number(kActorMutant2, 401);
return true;
case 404:
AI_Movement_Track_Flush(kActorMutant2);
AI_Movement_Track_Append(kActorMutant2, 39, 0);
AI_Movement_Track_Repeat(kActorMutant2);
return true;
case 410:
switch (Actor_Query_Which_Set_In(kActorMutant2)) {
case kSetUG01:
Non_Player_Actor_Combat_Mode_On(kActorMutant2, kActorCombatStateIdle, false, kActorMcCoy, 11, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG04:
// fall through
case kSetUG05:
// fall through
case kSetUG06:
Non_Player_Actor_Combat_Mode_On(kActorMutant2, kActorCombatStateIdle, false, kActorMcCoy, 10, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG10:
// fall through
case kSetUG12:
// fall through
case kSetUG14:
Non_Player_Actor_Combat_Mode_On(kActorMutant2, kActorCombatStateIdle, false, kActorMcCoy, 14, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
}
return true;
#if BLADERUNNER_ORIGINAL_BUGS
#else
case 411:
// We need the additional intermediate goal 411 (as mutant1 has)
// so that we set the health here, instead of the when the goal is set to 599 (dying)
// Setting the health "revives" the mutant, which would result in their bound box being reduced to a point
// (see Actor::setHealth() call to retire(false, 0, 0, -1))
// and thus their corpse being unclickable after McCoy shot them.
// Goal 411 does this, but is set only when McCoy is no longer present in the scene/set.
AI_Movement_Track_Flush(kActorMutant2);
Actor_Set_Intelligence(kActorMutant2, 20);
Actor_Set_Health(kActorMutant2, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant2, 60);
Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 30);
} else {
Actor_Set_Combat_Aggressiveness(kActorMutant2, 40);
Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 50);
}
// code repeated also in case 599 which precedes this one
// redundant?
// results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, -15);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 15);
Actor_Set_Goal_Number(kActorMutant2, 403);
return true;
#endif // BLADERUNNER_ORIGINAL_BUGS
case 590:
AI_Movement_Track_Flush(kActorMutant2);
AI_Movement_Track_Append(kActorMutant2, 39, 100);
AI_Movement_Track_Repeat(kActorMutant2);
return true;
case 599:
AI_Movement_Track_Flush(kActorMutant2);
Actor_Change_Animation_Mode(kActorMutant2, kAnimationModeDie);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Intelligence(kActorMutant2, 20);
Actor_Set_Health(kActorMutant2, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant2, 60);
Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 30);
} else {
Actor_Set_Combat_Aggressiveness(kActorMutant2, 40);
Actor_Set_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 50);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, -15);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 15);
return true;
}
return false;
}
bool AIScriptMutant2::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationMutant2Idle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2Idle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationMutant2Walking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2Walking)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationMutant2Running;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2Running)) {
_animationFrame = 0;
}
break;
case 3:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationMutant2Idle;
_animationState = 0;
} else {
*animation = kModelAnimationMutant2YellOrHurt;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2YellOrHurt)) {
_animationFrame = 0;
}
}
break;
case 4:
*animation = kModelAnimationMutant2YellOrHurt;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2YellOrHurt)) {
_animationFrame = 0;
_animationState = 3;
*animation = kModelAnimationMutant2CalmTalk;
}
break;
case 5:
*animation = kModelAnimationMutant2MeleeAttack;
++_animationFrame;
if (_animationFrame == 7) {
int snd;
if (Random_Query(1, 2) == 1) {
snd = 9010;
} else {
snd = 9015;
}
Sound_Play_Speech_Line(kActorMutant2, snd, 75, 0, 99);
}
if (_animationFrame == 9) {
Actor_Combat_AI_Hit_Attempt(kActorMutant2);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2MeleeAttack)) {
Actor_Change_Animation_Mode(kActorMutant2, kAnimationModeIdle);
}
break;
case 6:
*animation = kModelAnimationMutant2ShotDead;
++_animationFrame;
if (_animationFrame == 1) {
Sound_Play(kSfxYELL1M2, 100, 0, 0, 50);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
Actor_Change_Animation_Mode(kActorMutant2, 88);
}
break;
case 7:
*animation = kModelAnimationMutant2ShotDead;
// TODO why "- 2" here?
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2ShotDead) - 2;
break;
case 8:
*animation = kModelAnimationMutant2ShotDead;
_animationFrame += _var1;
if (_animationFrame == 4) {
_var1 = -1;
Sound_Play(kSfxHURT1M2, 100, 0, 0, 50);
} else {
if (_animationFrame == 0) {
Actor_Change_Animation_Mode(kActorMutant2, kAnimationModeIdle);
}
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptMutant2::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptMutant2::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState >= 3 && _animationState <= 4) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
// fall through
case kAnimationModeCombatWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeRun:
// fall through
case kAnimationModeCombatRun:
_animationState = 2;
_animationFrame = 0;
break;
case 3:
// fall through
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 4:
if (_animationState >= 3 && _animationState <= 4) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case 6:
_animationState = 5;
_animationFrame = 0;
break;
case 21:
// fall through
case 22:
_animationState = 8;
_animationFrame = 0;
_var1 = 1;
break;
case kAnimationModeDie:
_animationState = 6;
_animationFrame = 0;
break;
case 88:
_animationState = 7;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant2ShotDead) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptMutant2::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptMutant2::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMutant2::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMutant2::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptMutant2::FledCombat() {
Actor_Set_Goal_Number(kActorMutant2, 403);
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,672 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptMutant3::AIScriptMutant3(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_var1 = 1;
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptMutant3::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_var1 = 1;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Put_In_Set(kActorMutant3, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorMutant3, 39, 0);
Actor_Set_Goal_Number(kActorMutant3, 400);
}
bool AIScriptMutant3::Update() {
if (Global_Variable_Query(kVariableChapter) == 4) {
switch (Actor_Query_Goal_Number(kActorMutant3)) {
case 401:
if (Actor_Query_Which_Set_In(kActorMutant3) == Player_Query_Current_Set()
&& (Actor_Query_Friendliness_To_Other(kActorMutant3, kActorMcCoy) < 40
|| Actor_Query_Combat_Aggressiveness(kActorMutant3) >= 60
)
) {
Actor_Set_Goal_Number(kActorMutant3, 410);
}
break;
case 404:
if (!Game_Flag_Query(kFlagMutantsPaused)) {
Actor_Set_Goal_Number(kActorMutant3, 401);
}
break;
case 410:
if (Actor_Query_Which_Set_In(kActorMutant3) != Player_Query_Current_Set()) {
Non_Player_Actor_Combat_Mode_Off(kActorMutant3);
Actor_Set_Goal_Number(kActorMutant3, 403);
}
break;
case 599:
if (Actor_Query_Which_Set_In(kActorMutant3) != Player_Query_Current_Set()) {
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Goal_Number(kActorMutant3, 403);
#else
// intermediate goal to set new Health (revive for reuse)
Actor_Set_Goal_Number(kActorMutant3, 411);
#endif // BLADERUNNER_ORIGINAL_BUGS
}
break;
}
if (Game_Flag_Query(kFlagMutantsPaused)
&& Actor_Query_Goal_Number(kActorMutant3) != 599
) {
Actor_Set_Goal_Number(kActorMutant3, 404);
}
} else if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorMutant3) != 590
) {
if (Actor_Query_Which_Set_In(kActorMutant3) != Player_Query_Current_Set()) {
Actor_Set_Goal_Number(kActorMutant3, 590);
}
}
return false;
}
void AIScriptMutant3::TimerExpired(int timer) {
//return false;
}
void AIScriptMutant3::CompletedMovementTrack() {
switch (Actor_Query_Goal_Number(kActorMutant3)) {
case 201:
Actor_Set_Goal_Number(kActorMutant3, 400);
break;
case 401:
Actor_Set_Goal_Number(kActorMutant3, 403);
break;
}
}
void AIScriptMutant3::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptMutant3::ClickedByPlayer() {
//return false;
}
void AIScriptMutant3::EnteredSet(int setId) {
// return false;
}
void AIScriptMutant3::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptMutant3::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptMutant3::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (Actor_Query_Which_Set_In(kActorMutant3) == Player_Query_Current_Set()
&& Actor_Query_Goal_Number(kActorMutant3) != 599
) {
if (otherActorId == kActorMcCoy) {
if (combatMode) {
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 10);
} else {
Actor_Modify_Combat_Aggressiveness(kActorMutant3, -10);
}
} else if (otherActorId == kActorFreeSlotA
|| otherActorId == kActorMutant1
|| otherActorId == kActorMutant2
) {
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 5);
} else {
Actor_Modify_Combat_Aggressiveness(kActorMutant3, -10);
}
}
}
void AIScriptMutant3::ShotAtAndMissed() {
if (Actor_Query_Goal_Number(kActorMutant3) != 410) {
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 15);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -15);
}
}
bool AIScriptMutant3::ShotAtAndHit() {
if (Actor_Query_Goal_Number(kActorMutant3) != 410) {
Actor_Modify_Combat_Aggressiveness(kActorMutant3, 20);
Actor_Modify_Friendliness_To_Other(kActorMutant3, kActorMcCoy, -20);
}
return false;
}
void AIScriptMutant3::Retired(int byActorId) {
Actor_Set_Goal_Number(kActorMutant3, 599);
}
int AIScriptMutant3::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptMutant3::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 201:
AI_Movement_Track_Flush(kActorMutant3);
AI_Movement_Track_Append(kActorMutant3, 305, 3);
AI_Movement_Track_Append(kActorMutant3, 306, 0);
AI_Movement_Track_Append(kActorMutant3, 39, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 400:
AI_Movement_Track_Flush(kActorMutant3);
AI_Movement_Track_Append(kActorMutant3, 39, 0);
AI_Movement_Track_Repeat(kActorMutant3);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant3, 80);
Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 20);
}
break;
case 401:
Actor_Set_Targetable(kActorMutant3, true);
AI_Movement_Track_Flush(kActorMutant3);
AI_Movement_Track_Append(kActorMutant3, 39, 0);
switch (Random_Query(1, 8)) {
case 1:
AI_Movement_Track_Append(kActorMutant3, 182, 0);
AI_Movement_Track_Append(kActorMutant3, 183, 2);
AI_Movement_Track_Append(kActorMutant3, 184, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 2:
AI_Movement_Track_Append(kActorMutant3, 296, 0);
AI_Movement_Track_Append(kActorMutant3, 297, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 3:
AI_Movement_Track_Append(kActorMutant3, 176, 0);
AI_Movement_Track_Append(kActorMutant3, 177, 0);
AI_Movement_Track_Append(kActorMutant3, 178, 2);
AI_Movement_Track_Append(kActorMutant3, 177, 0);
AI_Movement_Track_Append(kActorMutant3, 176, 1);
AI_Movement_Track_Append(kActorMutant3, 39, 45);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 4:
AI_Movement_Track_Append(kActorMutant3, 298, 0);
AI_Movement_Track_Append(kActorMutant3, 300, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 5:
AI_Movement_Track_Append(kActorMutant3, 301, 0);
AI_Movement_Track_Append(kActorMutant3, 302, 2);
AI_Movement_Track_Append(kActorMutant3, 303, 0);
AI_Movement_Track_Append(kActorMutant3, 304, 2);
AI_Movement_Track_Append(kActorMutant3, 305, 0);
AI_Movement_Track_Append(kActorMutant3, 304, 0);
AI_Movement_Track_Append(kActorMutant3, 306, 0);
AI_Movement_Track_Append(kActorMutant3, 39, 60);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 6:
AI_Movement_Track_Append(kActorMutant3, 307, 0);
AI_Movement_Track_Append(kActorMutant3, 308, 0);
AI_Movement_Track_Append(kActorMutant3, 309, 1);
AI_Movement_Track_Append(kActorMutant3, 310, 3);
AI_Movement_Track_Append(kActorMutant3, 311, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 7:
switch (Random_Query(1, 5)) {
case 1:
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 534, 0);
AI_Movement_Track_Append(kActorMutant3, 535, 0);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 2:
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 535, 1);
AI_Movement_Track_Append(kActorMutant3, 534, 3);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 3:
AI_Movement_Track_Append(kActorMutant3, 536, 0);
AI_Movement_Track_Append(kActorMutant3, 537, 0);
AI_Movement_Track_Append(kActorMutant3, 538, 2);
AI_Movement_Track_Append(kActorMutant3, 537, 0);
AI_Movement_Track_Append(kActorMutant3, 536, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 4:
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 534, 3);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 5:
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 535, 1);
AI_Movement_Track_Append(kActorMutant3, 533, 0);
AI_Movement_Track_Append(kActorMutant3, 532, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
}
break;
case 8:
AI_Movement_Track_Append(kActorMutant3, 176, 0);
AI_Movement_Track_Append(kActorMutant3, 177, 0);
AI_Movement_Track_Append(kActorMutant3, 176, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
default:
AI_Movement_Track_Append(kActorMutant3, 39, 60);
AI_Movement_Track_Repeat(kActorMutant3);
break;
}
break;
case 403:
Actor_Set_Targetable(kActorMutant3, false);
Actor_Set_Goal_Number(kActorMutant3, 401);
break;
case 404:
AI_Movement_Track_Flush(kActorMutant3);
AI_Movement_Track_Append(kActorMutant3, 39, 0);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 410:
switch (Actor_Query_Which_Set_In(kActorMutant3)) {
case kSetUG01:
Non_Player_Actor_Combat_Mode_On(kActorMutant3, kActorCombatStateIdle, false, kActorMcCoy, 11, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG04:
// fall through
case kSetUG05:
// fall through
case kSetUG06:
Non_Player_Actor_Combat_Mode_On(kActorMutant3, kActorCombatStateIdle, false, kActorMcCoy, 10, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
case kSetUG10:
// fall through
case kSetUG12:
// fall through
case kSetUG14:
Non_Player_Actor_Combat_Mode_On(kActorMutant3, kActorCombatStateIdle, false, kActorMcCoy, 14, kAnimationModeCombatIdle, kAnimationModeCombatWalk, kAnimationModeCombatRun, -1, -1, -1, 10, 300, false);
break;
}
break;
#if BLADERUNNER_ORIGINAL_BUGS
#else
case 411:
// We need the additional intermediate goal 411 (as mutant1 has)
// so that we set the health here, instead of the when the goal is set to 599 (dying)
// Setting the health "revives" the mutant, which would result in their bound box being reduced to a point
// (see Actor::setHealth() call to retire(false, 0, 0, -1))
// and thus their corpse being unclickable after McCoy shot them.
// Goal 411 does this, but is set only when McCoy is no longer present in the scene/set.
AI_Movement_Track_Flush(kActorMutant3);
Actor_Set_Intelligence(kActorMutant3, 40);
Actor_Set_Health(kActorMutant3, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant3, 80);
Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 20);
} else {
Actor_Set_Combat_Aggressiveness(kActorMutant3, 50);
Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 40);
}
// code repeated also in case 599 which precedes this one
// redundant?
// results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 20);
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 15);
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
Actor_Set_Goal_Number(kActorMutant3, 403);
return true;
#endif // BLADERUNNER_ORIGINAL_BUGS
case 590:
AI_Movement_Track_Flush(kActorMutant3);
AI_Movement_Track_Append(kActorMutant3, 39, 100);
AI_Movement_Track_Repeat(kActorMutant3);
break;
case 599:
AI_Movement_Track_Flush(kActorMutant3);
Actor_Change_Animation_Mode(kActorMutant3, kAnimationModeDie);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Set_Intelligence(kActorMutant3, 40);
Actor_Set_Health(kActorMutant3, 10 * Query_Difficulty_Level() + 50, 10 * Query_Difficulty_Level() + 50);
if (Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)) {
Actor_Set_Combat_Aggressiveness(kActorMutant3, 80);
Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 20);
} else {
Actor_Set_Combat_Aggressiveness(kActorMutant3, 50);
Actor_Set_Friendliness_To_Other(kActorMutant3, kActorMcCoy, 40);
}
#endif // BLADERUNNER_ORIGINAL_BUGS
// results in additional reduction in friendliness and increase of aggressiveness for the other two mutants
Actor_Modify_Friendliness_To_Other(kActorMutant1, kActorMcCoy, 20);
Actor_Modify_Friendliness_To_Other(kActorMutant2, kActorMcCoy, 15);
Actor_Modify_Combat_Aggressiveness(kActorMutant1, 10);
Actor_Modify_Combat_Aggressiveness(kActorMutant2, 10);
break;
default:
return false;
}
return true;
}
bool AIScriptMutant3::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationMutant3Idle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3Idle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationMutant3Walking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3Walking)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationMutant3Running;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3Running)) {
_animationFrame = 0;
}
break;
case 3:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationMutant3Idle;
_animationState = 0;
} else {
*animation = kModelAnimationMutant3YellOrHurt;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3YellOrHurt)) {
_animationFrame = 0;
}
}
break;
case 4:
*animation = kModelAnimationMutant3YellOrHurt;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3YellOrHurt)) {
_animationFrame = 0;
_animationState = 3;
*animation = kModelAnimationMutant3CalmTalk;
}
break;
case 5:
*animation = kModelAnimationMutant3PicksUpAndThrowsRock;
++_animationFrame;
if (_animationFrame == 9) {
int snd;
if (Random_Query(1, 2) == 1) {
snd = 9010;
} else {
snd = 9015;
}
Sound_Play_Speech_Line(kActorMutant3, snd, 75, 0, 99);
}
if (_animationFrame == 11) {
Actor_Combat_AI_Hit_Attempt(kActorMutant3);
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
Actor_Change_Animation_Mode(kActorMutant3, kAnimationModeIdle);
}
break;
case 6:
*animation = kModelAnimationMutant3ShotDead;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3ShotDead)) {
Actor_Change_Animation_Mode(kActorMutant3, 88);
}
break;
case 7:
*animation = kModelAnimationMutant3ShotDead;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3ShotDead) - 1;
break;
case 8:
*animation = kModelAnimationMutant3CrouchedWaiting;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3CrouchedWaiting)) {
_animationFrame = 0;
}
break;
case 9:
*animation = kModelAnimationMutant3CrouchedFromStanding;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3CrouchedFromStanding)) {
_animationFrame = 0;
_animationState = 8;
*animation = kModelAnimationMutant3CrouchedWaiting;
}
break;
case 10:
*animation = kModelAnimationMutant3CrouchedToStanding;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3CrouchedToStanding)) {
*animation = kModelAnimationMutant3Idle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 11:
*animation = kModelAnimationMutant3ShotDead;
_animationFrame += _var1;
if (_animationFrame == 3) {
Sound_Play(kSfxHURT1M3, 100, 0, 0, 50);
_var1 = -1;
} else {
if (_animationFrame == 0) {
Actor_Change_Animation_Mode(kActorMutant3, kAnimationModeIdle);
}
}
break;
default:
// Dummy placeholder, kModelAnimationZubenIdle (406) is a Zuben animation
*animation = kModelAnimationZubenIdle;
debugC(6, kDebugAnimation, "AIScriptMutant3::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptMutant3::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
switch (_animationState) {
case 3:
// fall through
case 4:
_resumeIdleAfterFramesetCompletesFlag = true;
break;
case 8:
_animationState = 10;
_animationFrame = 0;
break;
case 10:
return true;
default:
_animationState = 0;
_animationFrame = 0;
break;
}
break;
case kAnimationModeWalk:
// fall through
case kAnimationModeCombatWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeRun:
// fall through
case kAnimationModeCombatRun:
_animationState = 2;
_animationFrame = 0;
break;
case 3:
// fall through
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 4:
if (_animationState >= 3 && _animationState <= 4) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case 6:
_animationState = 5;
_animationFrame = 0;
break;
case 21:
// fall through
case 22:
_animationState = 11;
_animationFrame = 0;
_var1 = 1;
break;
case 43:
if ((unsigned int)(_animationState - 8) > 1) {
_animationState = 9;
_animationFrame = 0;
}
break;
case kAnimationModeDie:
_animationState = 6;
_animationFrame = 0;
break;
case 88:
_animationState = 7;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationMutant3ShotDead) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptMutant3::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptMutant3::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptMutant3::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptMutant3::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptMutant3::FledCombat() {
Actor_Set_Goal_Number(kActorMutant3, 403);
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptNewscaster::AIScriptNewscaster(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptNewscaster::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptNewscaster::Update() {
return false;
}
void AIScriptNewscaster::TimerExpired(int timer) {
//return false;
}
void AIScriptNewscaster::CompletedMovementTrack() {
//return false;
}
void AIScriptNewscaster::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptNewscaster::ClickedByPlayer() {
//return false;
}
void AIScriptNewscaster::EnteredSet(int setId) {
// return false;
}
void AIScriptNewscaster::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptNewscaster::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptNewscaster::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptNewscaster::ShotAtAndMissed() {
// return false;
}
bool AIScriptNewscaster::ShotAtAndHit() {
return false;
}
void AIScriptNewscaster::Retired(int byActorId) {
// return false;
}
int AIScriptNewscaster::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptNewscaster::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptNewscaster::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptNewscaster::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptNewscaster::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptNewscaster::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptNewscaster::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptNewscaster::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,394 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptPhotographer::AIScriptPhotographer(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_varNumOfTimesToHoldCurrentFrame = 0;
_var2 = 0; // is always set to 0, never checked, unused
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptPhotographer::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
_var2 = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
}
bool AIScriptPhotographer::Update() {
if ( Game_Flag_Query(kFlagTB02ElevatorToTB05)
&& !Game_Flag_Query(kFlagTB06Photographer)
) {
Actor_Put_In_Set(kActorPhotographer, kSetFreeSlotC);
Actor_Set_At_Waypoint(kActorPhotographer, 35, 0);
Game_Flag_Set(kFlagTB06Photographer);
Actor_Set_Goal_Number(kActorPhotographer, 100);
return true;
}
return false;
}
void AIScriptPhotographer::TimerExpired(int timer) {
//return false;
}
void AIScriptPhotographer::CompletedMovementTrack() {
switch (Actor_Query_Goal_Number(kActorPhotographer)) {
case 100:
Actor_Set_Goal_Number(kActorPhotographer, 101);
break;
case 101:
Actor_Set_Goal_Number(kActorPhotographer, 102);
break;
case 102:
Actor_Set_Goal_Number(kActorPhotographer, 101);
break;
default:
return; //false;
}
return; //true;
}
void AIScriptPhotographer::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptPhotographer::ClickedByPlayer() {
if ( Actor_Clue_Query(kActorMcCoy, kClueDragonflyEarring)
&& !Actor_Clue_Query(kActorMcCoy, kClueVictimInformation)
&& !Game_Flag_Query(kFlagTB06PhotographTalk1)
) {
AI_Movement_Track_Pause(kActorPhotographer);
Actor_Face_Actor(kActorMcCoy, kActorPhotographer, true);
Actor_Says(kActorMcCoy, 5300, 14);
Actor_Face_Actor(kActorPhotographer, kActorMcCoy, true);
Actor_Says(kActorPhotographer, 20, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 5305, 15);
Game_Flag_Set(kFlagTB06PhotographTalk1);
AI_Movement_Track_Unpause(kActorPhotographer);
} else {
AI_Movement_Track_Pause(kActorPhotographer);
Actor_Face_Actor(kActorMcCoy, kActorPhotographer, true);
Actor_Face_Actor(kActorPhotographer, kActorMcCoy, true);
if (_vm->_cutContent && Random_Query(1, 10) < 3) {
Actor_Says(kActorMcCoy, 8516, 14); // Any idea if they were real dogs? (gets no answer)
Actor_Says(kActorPhotographer, 60, kAnimationModeTalk);
} else {
Actor_Says(kActorMcCoy, 5310, 11);
Actor_Says(kActorPhotographer, 40, kAnimationModeTalk);
}
AI_Movement_Track_Unpause(kActorPhotographer);
}
}
void AIScriptPhotographer::EnteredSet(int setId) {
// return false;
}
void AIScriptPhotographer::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptPhotographer::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptPhotographer::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptPhotographer::ShotAtAndMissed() {
// return false;
}
bool AIScriptPhotographer::ShotAtAndHit() {
return false;
}
void AIScriptPhotographer::Retired(int byActorId) {
// return false;
}
int AIScriptPhotographer::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptPhotographer::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 100:
AI_Movement_Track_Flush(kActorPhotographer);
AI_Movement_Track_Append(kActorPhotographer, 35, 0);
AI_Movement_Track_Repeat(kActorPhotographer);
return true;
case 101:
AI_Movement_Track_Flush(kActorPhotographer);
switch (Random_Query(1, 3)) {
case 1:
AI_Movement_Track_Append(kActorPhotographer, 280, 4);
break;
case 2:
AI_Movement_Track_Append(kActorPhotographer, 279, 8);
break;
case 3:
AI_Movement_Track_Append(kActorPhotographer, 280, 3);
break;
}
AI_Movement_Track_Repeat(kActorPhotographer);
return false;
case 102:
AI_Movement_Track_Flush(kActorPhotographer);
AI_Movement_Track_Append(kActorPhotographer, 279, 5);
AI_Movement_Track_Repeat(kActorPhotographer);
return true;
case 199:
Actor_Put_In_Set(kActorPhotographer, kSetFreeSlotC);
Actor_Set_At_Waypoint(kActorPhotographer, 35, 0);
Actor_Put_In_Set(kActorMarcus, kSetFreeSlotI);
Actor_Set_At_Waypoint(kActorMarcus, 41, 0);
if (Game_Flag_Query(kFlagTB06Visited)) {
Item_Remove_From_World(kItemDeadDogA);
Item_Remove_From_World(kItemDeadDogB);
Item_Remove_From_World(kItemDeadDogC);
}
if (!Actor_Clue_Query(kActorMcCoy, kClueDogCollar1)) {
Actor_Clue_Acquire(kActorSteele, kClueDogCollar1, true, -1);
if (Game_Flag_Query(kFlagTB06Visited)) {
Item_Remove_From_World(kItemDogCollar);
}
Global_Variable_Increment(kVariableMcCoyEvidenceMissed, 1);
}
return true;
default:
return true;
}
}
bool AIScriptPhotographer::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationPhotographerIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationPhotographerWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerWalking)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationPhotographerCalmTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationPhotographerIdle;
_animationState = 0;
_var2 = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerCalmTalk)) {
_animationFrame = 0;
}
}
break;
case 3:
#if BLADERUNNER_ORIGINAL_BUGS
// TODO A bug? This is identical to case 4 for animation 749, but 748 talk animation is left unused
*animation = kModelAnimationPhotographerExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerExplainTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationPhotographerCalmTalk;
}
#else
*animation = kModelAnimationPhotographerMoreHeadMoveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerMoreHeadMoveTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationPhotographerCalmTalk;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
break;
case 4:
*animation = kModelAnimationPhotographerExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerExplainTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationPhotographerCalmTalk;
}
break;
case 5:
*animation = kModelAnimationPhotographerSuggestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerSuggestTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationPhotographerCalmTalk;
}
break;
case 6:
*animation = kModelAnimationPhotographerTakingAPhoto;
if (_animationFrame == 11) {
Ambient_Sounds_Play_Sound(kSfxCAMCOP1, 80, -20, -20, 20);
}
if (_varNumOfTimesToHoldCurrentFrame) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
++_animationFrame;
if (_animationFrame == 10) {
_varNumOfTimesToHoldCurrentFrame = 5;
}
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationPhotographerTakingAPhoto)) {
*animation = kModelAnimationPhotographerIdle;
_animationState = 0;
_animationFrame = 0;
Actor_Change_Animation_Mode(kActorPhotographer, kAnimationModeIdle);
}
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptPhotographer::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptPhotographer::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState < 2 || _animationState > 5) {
_animationState = 0;
_var2 = 0;
_animationFrame = 0;
} else {
_resumeIdleAfterFramesetCompletesFlag = true;
}
break;
case kAnimationModeWalk:
_animationState = 1;
_var2 = 0;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 2;
_var2 = 0;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 3;
_var2 = 0;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 4;
_var2 = 0;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 5;
_var2 = 0;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 43:
_animationState = 6;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptPhotographer::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptPhotographer::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptPhotographer::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptPhotographer::ReachedMovementTrackWaypoint(int waypointId) {
if (waypointId == 276
|| waypointId == 278
|| waypointId == 280
) {
ChangeAnimationMode(43);
}
return true;
}
void AIScriptPhotographer::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,598 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptRachael::AIScriptRachael(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = true;
}
void AIScriptRachael::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = true;
Actor_Set_Goal_Number(kActorRachael, kGoalRachaelDefault);
}
bool AIScriptRachael::Update() {
if (_vm->_cutContent) {
if (Global_Variable_Query(kVariableChapter) == 3) {
if (Actor_Query_Goal_Number(kActorRachael) == kGoalRachaelLeavesAfterTyrellMeeting) {
// Decide 50-50 whether Rachael will be encountered outside or in the elevator in Act 3
if (Random_Query(1,2 ) == 1) {
Actor_Set_Goal_Number(kActorRachael, kGoalRachaelShouldBeOutsideMcCoysAct3);
} else {
Actor_Set_Goal_Number(kActorRachael, kGoalRachaelShouldBeInElevatorMcCoysAct3);
}
return true;
}
} else if (Global_Variable_Query(kVariableChapter) == 4) {
if (Actor_Query_Goal_Number(kActorRachael) < 399) {
Actor_Set_Goal_Number(kActorRachael, kGoalRachaelAtEndOfAct3IfNotMetWithMcCoy);
return true;
}
} else if (Global_Variable_Query(kVariableChapter) > 4
&& Actor_Query_Goal_Number(kActorRachael) != kGoalRachaelAtEndOfAct4) {
Actor_Set_Goal_Number(kActorRachael, kGoalRachaelAtEndOfAct4);
return true;
}
}
return false;
}
void AIScriptRachael::TimerExpired(int timer) {
//return false;
}
void AIScriptRachael::CompletedMovementTrack() {
//return false;
}
void AIScriptRachael::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptRachael::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorRachael) == 305) {
Actor_Face_Actor(kActorMcCoy, kActorRachael, true);
Actor_Says(kActorMcCoy, 2730, 12); // "Rachael, right?"
AI_Movement_Track_Pause(kActorRachael);
dialogue_start(); // "I remember you mr McCoy" till "I'm fine, thank you for asking."
// the structure is simplified (maintaining the same logic flow)
if ((Player_Query_Agenda() == kPlayerAgendaSurly || Player_Query_Agenda() == kPlayerAgendaErratic)
|| (Player_Query_Agenda() != kPlayerAgendaPolite && Actor_Query_Friendliness_To_Other(kActorSteele, kActorMcCoy) > Actor_Query_Friendliness_To_Other(kActorClovis, kActorMcCoy))
) {
dialogue_agenda2();
} else {
dialogue_agenda1();
}
Actor_Set_Goal_Number(kActorRachael, kGoalRachaelIsOutResumesWalkToPoliceHQAct3);
AI_Movement_Track_Unpause(kActorRachael);
}
}
void AIScriptRachael::EnteredSet(int setId) {
// return false;
}
void AIScriptRachael::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptRachael::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptRachael::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptRachael::ShotAtAndMissed() {
// return false;
}
bool AIScriptRachael::ShotAtAndHit() {
return false;
}
void AIScriptRachael::Retired(int byActorId) {
// return false;
}
int AIScriptRachael::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptRachael::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalRachaelLeavesAfterTyrellMeeting:
AI_Movement_Track_Flush(kActorRachael);
// TODO Wouldn't it be better to use only waypoint 468 and then flush movement (or pause)
// at CompletedMovementTrack()
// instead of having her walk to waypoint 39 (in kSetFreeSlotG)?
AI_Movement_Track_Append(kActorRachael, 379, 0); // kSetTB07
AI_Movement_Track_Append(kActorRachael, 39, 0); // kSetFreeSlotG
AI_Movement_Track_Repeat(kActorRachael);
break;
case kGoalRachaelIsOutsideMcCoysBuildingAct4:
// added goal for restored content
// fall through
case kGoalRachaelIsOutsideMcCoysBuildingAct3:
// This puts Rachael outside McCoy's building
Actor_Put_In_Set(kActorRachael, kSetMA07);
Actor_Set_At_XYZ(kActorRachael, -8.09f, -162.8f, 135.33f, 544);
break;
case kGoalRachaelIsInsideElevatorStartTalkAct3:
// added goal for restored content
dialogue_start(); // "I remember you mr McCoy" till "I'm fine, thank you for asking."
// the structure is simplified (maintaining the same logic flow)
if ((Player_Query_Agenda() == kPlayerAgendaSurly || Player_Query_Agenda() == kPlayerAgendaErratic)
|| (Player_Query_Agenda() != kPlayerAgendaPolite && Actor_Query_Friendliness_To_Other(kActorSteele, kActorMcCoy) > Actor_Query_Friendliness_To_Other(kActorClovis, kActorMcCoy))
) {
dialogue_agenda2();
} else {
dialogue_agenda1();
}
break;
case kGoalRachaelIsInsideElevatorStartTalkAct4:
dialogue_act4();
break;
case kGoalRachaelIsOutWalksToPoliceHQAct4:
// added goal for restored content
// fall through
case kGoalRachaelIsOutWalksToPoliceHQAct3:
// Rachael's goal is set to this when the player walks in the MA07 scene and if her goal is already kGoalRachaelIsOutsideMcCoysBuildingAct3
AI_Movement_Track_Flush(kActorRachael);
// This makes Rachael (who is right outside McCoy's building) head towards the Police Station (left)
// TODO Wouldn't it be better to use only waypoint 468 and then flush movement (or pause)
// at CompletedMovementTrack()
// instead of having her walk to waypoint 39 (in kSetFreeSlotG)?
AI_Movement_Track_Append(kActorRachael, 468, 0); // kSetMA07
AI_Movement_Track_Append(kActorRachael, 39, 0); // kSetFreeSlotG
AI_Movement_Track_Repeat(kActorRachael);
break;
case kGoalRachaelAtEndOfAct3IfNotMetWithMcCoy:
// added goal for restored content
// fall through
case kGoalRachaelAtEndOfAct4:
// added goal for restored content
// fall through
case kGoalRachaelAtEndOfAct3IfMetWithMcCoy:
AI_Movement_Track_Pause(kActorRachael);
Actor_Put_In_Set(kActorRachael, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorRachael, 39, 0);
break;
default:
return false;
}
return true;
}
bool AIScriptRachael::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationRachaelIdle;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelIdle) - 1) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationRachaelWalking;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelWalking) - 1) {
_animationFrame = 0;
}
break;
case 2:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationRachaelIdle;
_animationState = 0;
} else {
*animation = kModelAnimationRachaelTalkSoftNod;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkSoftNod) - 1) {
_animationFrame = 0;
}
}
break;
case 3:
*animation = kModelAnimationRachaelTalkNodToLeft;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkNodToLeft) - 1) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationRachaelTalkSoftNod;
}
break;
case 4:
*animation = kModelAnimationRachaelTalkSuggestWithNodToLeft;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkSuggestWithNodToLeft) - 1) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationRachaelTalkSoftNod;
}
break;
case 5:
*animation = kModelAnimationRachaelTalkIndiffWithNodToLeft;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkIndiffWithNodToLeft) - 1) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationRachaelTalkSoftNod;
}
break;
case 6:
*animation = kModelAnimationRachaelTalkOfferPointing;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkOfferPointing) - 1) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationRachaelTalkSoftNod;
}
break;
case 7:
*animation = kModelAnimationRachaelTalkHaltMovement;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkHaltMovement) - 1) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationRachaelTalkSoftNod;
}
break;
case 8:
*animation = kModelAnimationRachaelTalkHandOnChest;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkHandOnChest) - 1) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationRachaelTalkSoftNod;
}
break;
case 9:
*animation = kModelAnimationRachaelTalkHandWaveToRight;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationRachaelTalkHandWaveToRight) - 1) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationRachaelTalkSoftNod;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptRachael::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptRachael::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState >= 2 && _animationState <= 9) { // talking states
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0; // idle state
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 16:
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 17:
_animationState = 8;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 18:
_animationState = 9;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
default:
debugC(6, kDebugAnimation, "AIScriptRachael::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptRachael::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptRachael::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptRachael::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptRachael::FledCombat() {
// return false;
}
void AIScriptRachael::dialogue_start() {
if (_vm->_cutContent) {
Actor_Face_Actor(kActorRachael, kActorMcCoy, true);
Loop_Actor_Walk_To_Actor(kActorRachael, kActorMcCoy, 84, false, false);
if (_vm->_cutContent) {
Actor_Says(kActorMcCoy, 2735, 14); // MetAtYourUnclesOffice
}
Actor_Says(kActorRachael, 0, 15); // RememberYouMisterMcCoy
Actor_Says(kActorMcCoy, 2740, 13); // YouLiveHereSameBuilding
Actor_Says(kActorRachael, 10, 14); // VisitingSomebody
Actor_Says(kActorMcCoy, 2745, 13); // WhoMaybeIKnowHim
Actor_Says(kActorRachael, 20, 12); // NoneOfYourBusiness
Actor_Says_With_Pause(kActorMcCoy, 2750, 1.5f, 3); // OkGetThePicture
Actor_Says(kActorMcCoy, 2755, 3); // AreYouAlrightALittlePale
Actor_Says(kActorRachael, 30, 13); // CertainlyHadBetterDaysInMyLifeButImFine
Actor_Says(kActorRachael, 40, 15); // ThankYouForAsking
} else {
// original code -- un-triggered
Loop_Actor_Walk_To_Actor(kActorRachael, kActorMcCoy, 84, false, false);
Actor_Says(kActorRachael, 0, 15); // I remember you mr mcCoy
Actor_Says(kActorMcCoy, 2740, 13);
Actor_Says(kActorRachael, 10, 14);
Actor_Says(kActorMcCoy, 2745, 13);
Actor_Says(kActorRachael, 20, 12); // perhaps none of your business
Actor_Says_With_Pause(kActorMcCoy, 2750, 1.5f, 3); // ok I get the picture
Actor_Says(kActorRachael, 30, 13); // certainly had better days but i'm fine
Actor_Says(kActorRachael, 40, 15); // Thank you for asking
}
}
void AIScriptRachael::dialogue_agenda1() {
// polite or Rep friendly case
if (_vm->_cutContent) {
Actor_Says(kActorMcCoy, 2795, 13); // YouAreUpset
Actor_Says(kActorRachael, 140, 15); // HowObservant
Actor_Says(kActorMcCoy, 2800, 12); // WhatTheMatterGoodListener
Actor_Says(kActorRachael, 150, 16); // HowObservant
Actor_Says(kActorMcCoy, 2805, 18); // DidYourUncleSaySomethingToYou
Actor_Says(kActorRachael, 160, 14); // HeCanBeSoCruel
Actor_Says(kActorRachael, 170, 13); // HereIAmPouringMyHeartOut
Actor_Says(kActorMcCoy, 2810, 14); // NotHowILookAtIt
Actor_Says(kActorRachael, 180, 13); // GotToLiveWithYourself
Actor_Says(kActorMcCoy, 2815, 12); // NotSomeKillingMachineRachael
Actor_Says(kActorMcCoy, 2820, 13); // LatelyReEvalTheJobDontLikeItNeverHave - I've thought ab... Well lately reevaluating the job dont like it
Actor_Says(kActorRachael, 190, 15); // WhyDontYouQuitThen
Actor_Says(kActorMcCoy, 2825, 12); // SomeoneWouldJustTakeMyPlace
Actor_Says(kActorRachael, 200, 15); // SoMuchForIntegrity
Actor_Says(kActorMcCoy, 2830, 14); // ItsNotThat
Actor_Says(kActorRachael, 210, 15); // ItsTheMoneyThen
Actor_Says(kActorRachael, 220, 16); // ImSoFedUpWithAllOfIt
Actor_Says(kActorMcCoy, 2835, 13); // IveThinkingAboutTheTreatmentOfReps
Actor_Says(kActorRachael, 230, 14); // BravoShouldWeCallThePressConf - new switched to here
Actor_Says(kActorMcCoy, 2840, 12); // MaybeTheyVeGottenARawDeal
Actor_Says(kActorRachael, 240, 13); // ImagineSomebodyEngineeringYourMind
Actor_Says(kActorRachael, 250, 15); // PuttingWhateverThoughtsAndMemories
Actor_Says(kActorRachael, 260, 16); // NothingInThisWorldWouldBelongToyou
Actor_Says(kActorMcCoy, 2845, 13); // No
Actor_Says(kActorRachael, 270, 13); // ThinkAboutItMcCoy
Actor_Says(kActorRachael, 280, 14); // MaybeYouArentSoDifferentFromThoseRepsAfterAll
Actor_Says(kActorMcCoy, 2850, 13); // ISupposeAllRepsInOneWayOrAnother
Actor_Says(kActorMcCoy, 2855, 14); // ProgrammedToDoThingsThinkThings
Actor_Says(kActorRachael, 290, 14); // ThatsRight
if (Actor_Query_In_Set(kActorRachael, kSetMA07)) {
Actor_Says_With_Pause(kActorRachael, 300, 1.0f, 3); // GoodbyeMcCoy
Actor_Says(kActorMcCoy, 2860, 14); // YouTakeCareOfYourself
}
} else {
// original code
Actor_Says(kActorMcCoy, 2795, 13); // You are upset
Actor_Says(kActorRachael, 140, 15); // How observant
Actor_Says(kActorMcCoy, 2800, 12); // Whats the matter good listener
Actor_Says(kActorRachael, 150, 16); // ImSureYouAreMrMcCoyDontFeelLike
Actor_Says(kActorMcCoy, 2805, 18); // DidYourUncleSaySomethingToYou
Actor_Says(kActorRachael, 160, 14); // HeCanBeSoCruel
Actor_Says(kActorRachael, 170, 13); // HereIAmPouringMyHeartOut
Actor_Says(kActorMcCoy, 2810, 14); // NotHowILookAtIt
Actor_Says(kActorRachael, 180, 13); // GotToLiveWithYourself
Actor_Says(kActorMcCoy, 2815, 12); // NotSomeKillingMachineRachael
Actor_Says(kActorMcCoy, 2820, 13); //
Actor_Says(kActorRachael, 190, 15); // WhyDontYouQuitThen
Actor_Says(kActorMcCoy, 2825, 12); // SomeoneWouldJustTakeMyPlace
Actor_Says(kActorRachael, 200, 15); // SoMuchForIntegrity
Actor_Says(kActorMcCoy, 2830, 14); // ItsNotThat
Actor_Says(kActorRachael, 210, 15); // ItsTheMoneyThen
Actor_Says(kActorRachael, 220, 16); // ImSoFedUpWithAllOfIt
Actor_Says(kActorMcCoy, 2835, 13); // IveThinkingAboutTheTreatmentOfReps
Actor_Says(kActorRachael, 230, 14); // BravoShouldWeCallThePressConf
Actor_Says(kActorMcCoy, 2840, 12); // MaybeTheyVeGottenARawDeal
Actor_Says(kActorRachael, 240, 13); // ImagineSomebodyEngineeringYourMind
Actor_Says(kActorRachael, 250, 15); // PuttingWhateverThoughtsAndMemories
Actor_Says(kActorRachael, 260, 16); // NothingInThisWorldWouldBelongToyou
Actor_Says(kActorMcCoy, 2845, 13); // No
Actor_Says(kActorRachael, 270, 13); // ThinkAboutItMcCoy
Actor_Says(kActorRachael, 280, 14); // MaybeYouArentSoDifferentFromThoseRepsAfterAll
Actor_Says(kActorMcCoy, 2850, 13); // ISupposeAllRepsInOneWayOrAnother
Actor_Says(kActorRachael, 290, 14); // ThatsRight
Actor_Says_With_Pause(kActorRachael, 300, 1.0f, 3); // GoodbyeMcCoy
Actor_Says(kActorMcCoy, 2860, 14); // YouTakeCareOfYourself
}
}
void AIScriptRachael::dialogue_agenda2() {
// surly/erratic or human friendly case
if (_vm->_cutContent) {
Actor_Says(kActorMcCoy, 2760, 14); // InterestingGuyYourUncleCharacterator-Rachael
Actor_Says(kActorRachael, 50, 15); // IDontThinkHeDAppreciateBeingCalledThat new anim 15
Actor_Says(kActorMcCoy, 2765, 16); // ImSureHeIsABrilliantMan new anim 16
Actor_Says_With_Pause(kActorMcCoy, 2770, 0.0f, 17); // AnyoneWhoCouldCreateNexus6StateOfArt new anim 17
Actor_Says(kActorRachael, 60, 14); // KeepingPeopleLikeYouEmployedIsntHe
Actor_Says(kActorMcCoy, 2775, 16); // IdJustAsSoonNotDoThisJob.
Actor_Says(kActorRachael, 70, 13); // DoYouReallyExpectMeToBelieveThat
Actor_Says(kActorRachael, 80, 14); // ISawThatLookInYourEye
Actor_Says(kActorRachael, 90, 15); // LikeNothingButToKillInnocentPeople
Actor_Says(kActorMcCoy, 2780, 17); // ReplicantsArentPeople
Actor_Says(kActorRachael, 100, 16); // CertainlyAreMoreInnocentThanMostPeople
Actor_Says(kActorRachael, 110, 15); // TheyDidntAskToBeBroughtIntoThisWorld
Actor_Says(kActorMcCoy, 2785, 17); // NobodyDoes
Actor_Says(kActorRachael, 120, 13); // ThatsRightAndNobodyHasALicenseTokillHumans
Actor_Says(kActorMcCoy, 2790, 18); // Aha
Actor_Says(kActorRachael, 130, 14); // ButReplicantsHowHumain
if (Actor_Query_In_Set(kActorRachael, kSetMA07)) {
Actor_Says_With_Pause(kActorRachael, 300, 1.0f, 3); // GoodbyeMcCoy
Actor_Says(kActorMcCoy, 2860, 14); // YouTakeCareOfYourself
}
} else {
// original code - missing some quotes or removing some quotes to make it fit better
Actor_Says(kActorRachael, 50, 15); // I don't think he'd appreciate being called that
Actor_Says(kActorMcCoy, 2765, 16); // Oh i'm sure brilliant man
Actor_Says_With_Pause(kActorMcCoy, 2770, 0.0f, 17); // anyone who could create nexus -6
Actor_Says(kActorRachael, 60, 14); // keeping people like you employed
Actor_Says(kActorMcCoy, 2775, 16); // IdJustAsSoonNotDoThisJob
Actor_Says(kActorRachael, 70, 13); // do you really expect me to believe that
Actor_Says(kActorRachael, 80, 14); // ISawThatLookInYourEye
Actor_Says(kActorRachael, 90, 15); // LikeNothingButToKillInnocentPeople
Actor_Says(kActorMcCoy, 2780, 17); // ReplicantsArentPeople
Actor_Says(kActorRachael, 100, 16); // CertainlyAreMoreInnocentThanMostPeople
Actor_Says(kActorRachael, 110, 15); // TheyDidntAskToBeBroughtIntoThisWorld
Actor_Says(kActorMcCoy, 2785, 17); // NobodyDoes
Actor_Says(kActorRachael, 120, 13); // ThatsRightAndNobodyHasALicenseTokillHumans
Actor_Says(kActorMcCoy, 2790, 16); // Aha
Actor_Says(kActorRachael, 130, 14); // ButReplicantsHowHumain
Actor_Says_With_Pause(kActorRachael, 300, 1.0f, 3); // GoodbyeMcCoy
Actor_Says(kActorMcCoy, 2860, 14); // YouTakeCareOfYourself
}
}
// Not used in the game
void AIScriptRachael::dialogue_act4() {
Actor_Says(kActorMcCoy, 2865, 17); // Lobby
if (_vm->_cutContent) {
Game_Flag_Set(kFlagMA06toMA07); // to Ground Floor / Lobby
Delay(500);
AI_Movement_Track_Pause(kActorRachael);
Actor_Face_Actor(kActorRachael, kActorMcCoy, true);
}
Actor_Says(kActorRachael, 320, 12); // McCoy
Actor_Says(kActorRachael, 330, 17); // RachaelRememberMe
if (_vm->_cutContent) {
Actor_Face_Actor(kActorMcCoy, kActorRachael, true);
}
Actor_Says(kActorMcCoy, 2870, 13); // Jesus DontKnowWhatIRememberAnyMore
Actor_Says(kActorRachael, 340, 12); // NowYouLookInTrouble
Actor_Says(kActorMcCoy, 2875, 15); // Saw me here before
Actor_Says(kActorRachael, 350, 3); // YesWhatHappened
Actor_Says(kActorMcCoy, 2880, 16); // Suddenly
Actor_Says(kActorMcCoy, 2885, 12); // MyAnimalMaggiePrizedPosessionDisappeared
Actor_Says(kActorRachael, 360, 3); // ImSorry
Actor_Says(kActorRachael, 370, 3); // IKnowTheFeeling
Actor_Says(kActorMcCoy, 2890, 18); // You do?
Actor_Says(kActorRachael, 380, 18); // EverythingWeBelieve
Actor_Says(kActorRachael, 390, 12); // WhatIsReality
Actor_Says(kActorRachael, 400, 13); // MaybeAllSomeoneElsesFantasy
Actor_Says(kActorMcCoy, 2895, 14); // That would make us a fantasy
Actor_Says(kActorRachael, 410, 15); // ThatsRightAndInTheBlinkOfAnEyeGoesAway
Actor_Says_With_Pause(kActorMcCoy, 2900, 0.0f, 16); // But just yesterday
Actor_Says(kActorRachael, 420, 14); // YesterdayTwoMonthsAgo
Actor_Says_With_Pause(kActorMcCoy, 2905, 0.0f, 13); // ButIfWeBothRemembered
Actor_Says(kActorRachael, 430, 16); // CopiesOnlyCopies
Actor_Says(kActorRachael, 440, 12); // OnlyThingWeCanTrustIsNow
Actor_Says(kActorMcCoy, 2910, 14); // NotLosingMyMindEscapedReplicant
Actor_Says(kActorMcCoy, 2920, 17); // SomeoneSettingMeUpUsingMe
Actor_Says(kActorRachael, 450, 3); // NothingWrongWithAcceptingWhatYouAre
Actor_Says(kActorMcCoy, 2925, 15); // NotAReplicantGoddamnit
Actor_Says(kActorMcCoy, 2930, 14); // MaybeYouCanHelpMeYouAreTyrellsNiece
Actor_Says(kActorRachael, 460, 13); // Why not take that V-K test
Actor_Says(kActorMcCoy, 2935, 19); // YeahGoodIdeaMaybeIllDoThat
Actor_Says(kActorRachael, 470, 18); // Hope you get the answers looking for McCoy.
}
} // End of namespace BladeRunner

View File

@@ -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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/bladerunner.h"
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptRajif::AIScriptRajif(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptRajif::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
Actor_Set_Goal_Number(kActorRajif, 0);
}
bool AIScriptRajif::Update() {
if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Goal_Number(kActorRajif) < 400
)
Actor_Set_Goal_Number(kActorRajif, 599);
return false;
}
void AIScriptRajif::TimerExpired(int timer) {
//return false;
}
void AIScriptRajif::CompletedMovementTrack() {
//return false;
}
void AIScriptRajif::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptRajif::ClickedByPlayer() {
//return false;
}
void AIScriptRajif::EnteredSet(int setId) {
// return false;
}
void AIScriptRajif::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptRajif::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptRajif::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptRajif::ShotAtAndMissed() {
// return false;
}
bool AIScriptRajif::ShotAtAndHit() {
return false;
}
void AIScriptRajif::Retired(int byActorId) {
// return false;
}
int AIScriptRajif::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptRajif::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 300) {
Actor_Put_In_Set(kActorRajif, kSetMA02_MA04);
Actor_Set_At_XYZ(kActorRajif, -73.34f, -140.40f, 342.0f, 300);
Actor_Change_Animation_Mode(kActorRajif, kAnimationModeIdle);
return true;
}
if (newGoalNumber == 599) {
Actor_Put_In_Set(kActorRajif, kSetFreeSlotI);
Actor_Set_At_Waypoint(kActorRajif, 41, 0);
return true;
}
return false;
}
bool AIScriptRajif::UpdateAnimation(int *animation, int *frame) {
#if BLADERUNNER_ORIGINAL_BUGS
if (_animationState <= 1) {
if (_animationState > 0) {
*animation = kModelAnimationRajifWithGunIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRajifWithGunIdle)) {
_animationFrame = 0;
}
} else {
// bug in original. Both branches are equal. Also _animationState for Rajif is always 0.
*animation = kModelAnimationRajifWithGunIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRajifWithGunIdle)) {
_animationFrame = 0;
}
}
}
#else
switch (_animationState) {
case 0:
*animation = kModelAnimationRajifWithGunIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRajifWithGunIdle)) {
_animationFrame = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptRajif::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
#endif // BLADERUNNER_ORIGINAL_BUGS
*frame = _animationFrame;
return true;
}
bool AIScriptRajif::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptRajif::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptRajif::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptRajif::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptRajif::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptRajif::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,727 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
enum kRunciterStates {
kRunciterStateIdle = 0,
kRunciterStateWalking = 1,
kRunciterStateDying = 14,
kRunciterStateDead = 15
};
AIScriptRunciter::AIScriptRunciter(BladeRunnerEngine *vm) : AIScriptBase(vm) {
// _varChooseIdleAnimation can have valid values: 0, 1, 2
_varChooseIdleAnimation = 0;
var_45CD7C = 0;
var_45CD80 = 0;
_varNumOfTimesToHoldCurrentFrame = 0;
var_45CD88 = 0;
}
void AIScriptRunciter::Initialize() {
_animationState = 0;
_animationFrame = 0;
_animationStateNext = 0;
_varChooseIdleAnimation = 0;
var_45CD7C = 6;
var_45CD80 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
var_45CD88 = 0;
Actor_Set_Goal_Number(kActorRunciter, kGoalRunciterDefault);
}
bool AIScriptRunciter::Update() {
if (Actor_Query_Goal_Number(kActorRunciter) == kGoalRunciterDefault
&& Game_Flag_Query(kFlagRC01PoliceDone)
) {
Actor_Set_Goal_Number(kActorRunciter, kGoalRunciterGoToFreeSlotGH);
}
if (Global_Variable_Query(kVariableChapter) == 4
&& Actor_Query_Goal_Number(kActorRunciter) < kGoalRunciterRC02Wait
) {
Actor_Set_Goal_Number(kActorRunciter, kGoalRunciterRC02Wait);
}
return false;
}
void AIScriptRunciter::TimerExpired(int timer) {}
void AIScriptRunciter::CompletedMovementTrack() {
if (Actor_Query_Goal_Number(kActorRunciter) == kGoalRunciterRC02WalkAround) {
if (Player_Query_Current_Scene() == kSceneRC02) {
switch (Random_Query(1, 5)) {
case 2:
// fall through
case 3:
ADQ_Add(kActorRunciter, 530, -1);
break;
case 1:
// fall through
case 5:
ADQ_Add(kActorRunciter, 80, -1);
break;
case 4:
ADQ_Add(kActorRunciter, 930, -1);
break;
}
}
Actor_Set_Goal_Number(kActorRunciter, 99);
Actor_Set_Goal_Number(kActorRunciter, kGoalRunciterRC02WalkAround);
//return true;
}
//return false;
}
void AIScriptRunciter::ReceivedClue(int clueId, int fromActorId) {}
void AIScriptRunciter::ClickedByPlayer() {}
void AIScriptRunciter::EnteredSet(int setId) {}
void AIScriptRunciter::OtherAgentEnteredThisSet(int otherActorId) {}
void AIScriptRunciter::OtherAgentExitedThisSet(int otherActorId) {}
void AIScriptRunciter::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if ( Actor_Query_Goal_Number(kActorRunciter) == kGoalRunciterRC02Wait
&& combatMode
&& !Game_Flag_Query(kFlagRC02RunciterTalkWithGun)
) {
Actor_Set_Targetable(kActorRunciter, true);
Actor_Face_Actor(kActorRunciter, kActorMcCoy, true);
Actor_Says(kActorRunciter, 420, 12);
Actor_Face_Actor(kActorMcCoy, kActorRunciter, true);
// TODO revisit setting kActorMcCoy to Combat Aim via Actor_Change_Animation_Mode()
// (see notes in Gordo AI script in his CompletedMovementTrack())
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeCombatAim);
if (Actor_Clue_Query(kActorMcCoy, kClueZubensMotive)) {
Actor_Says(kActorMcCoy, 4770, -1);
Actor_Says(kActorRunciter, 590, 13);
Actor_Says(kActorMcCoy, 4775, -1);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorRunciter, 600, 17);
#else
// Runciter is interrupted here
Actor_Says_With_Pause(kActorRunciter, 600, 0.0f, 17);
#endif // BLADERUNNER_ORIGINAL_BUGS
Sound_Play(kSfxSHOTCOK1, 100, 0, 100, 50);
Actor_Says(kActorMcCoy, 4780, -1);
Actor_Says(kActorRunciter, 610, 18);
Actor_Says(kActorMcCoy, 4785, -1);
Actor_Says(kActorRunciter, 620, 15);
if (Game_Flag_Query(kFlagLucyIsReplicant)) {
Actor_Says(kActorRunciter, 630, 12);
Actor_Says(kActorRunciter, 640, 17);
Actor_Says(kActorMcCoy, 4790, -1);
Actor_Says(kActorRunciter, 650, 18);
if (_vm->_cutContent) {
Actor_Says(kActorMcCoy, 4800, -1);
}
Actor_Says(kActorRunciter, 660, 19);
Actor_Clue_Acquire(kActorMcCoy, kClueRuncitersConfession1, true, kActorRunciter);
} else {
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorRunciter, 670, 18);
#else
// Runciter is interrupted here
Actor_Says_With_Pause(kActorRunciter, 670, 0.0f, 18);
#endif // BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorMcCoy, 4795, -1);
Actor_Says(kActorRunciter, 730, 17);
}
} else if (Actor_Clue_Query(kActorMcCoy, kClueEnvelope)) {
Actor_Says(kActorMcCoy, 4730, -1);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorRunciter, 480, 17);
#else
// Runciter is kind of interrupted here
Actor_Says_With_Pause(kActorRunciter, 480, 0.0f, 17);
#endif // BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorMcCoy, 4735, -1);
Actor_Says(kActorRunciter, 490, 16);
Sound_Play(kSfxSHOTCOK1, 100, 0, 100, 50);
Actor_Says(kActorMcCoy, 4740, -1);
Actor_Says(kActorRunciter, 500, 18);
#if BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorRunciter, 510, 19);
#else
// Runciter is kind of interrupted here
Actor_Says_With_Pause(kActorRunciter, 510, 0.0f, 19);
#endif // BLADERUNNER_ORIGINAL_BUGS
Actor_Says(kActorMcCoy, 4745, -1);
Actor_Says(kActorMcCoy, 4750, -1);
if (_vm->_cutContent) {
Actor_Says(kActorMcCoy, 4755, -1); // M: Was the tiger a fake?
}
Actor_Says(kActorRunciter, 520, 17); // R: No! The tiger was real. I swear it.
Actor_Says(kActorRunciter, 530, 18);
Actor_Says(kActorRunciter, 540, 16);
}
Game_Flag_Set(kFlagRC02RunciterTalkWithGun);
}
}
void AIScriptRunciter::ShotAtAndMissed() {}
bool AIScriptRunciter::ShotAtAndHit() {
Actor_Set_Targetable(kActorRunciter, false);
Actor_Change_Animation_Mode(kActorRunciter, kAnimationModeDie);
Actor_Set_Goal_Number(kActorRunciter, kGoalRunciterDead);
Delay(2000);
if (Actor_Clue_Query(kActorMcCoy, kClueZubensMotive)) {
Actor_Voice_Over(2050, kActorVoiceOver);
Actor_Voice_Over(2060, kActorVoiceOver);
} else {
Actor_Voice_Over(2070, kActorVoiceOver);
Actor_Voice_Over(2080, kActorVoiceOver);
Actor_Voice_Over(2090, kActorVoiceOver);
}
Actor_Modify_Friendliness_To_Other(kActorClovis, kActorMcCoy, 3);
return false;
}
void AIScriptRunciter::Retired(int byActorId) {}
int AIScriptRunciter::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptRunciter::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == kGoalRunciterDefault) {
Actor_Put_In_Set(kActorRunciter, kSetRC02_RC51);
Actor_Set_At_Waypoint(kActorRunciter, 92, 567);
return false;
}
if (newGoalNumber == kGoalRunciterRC02WalkAround) {
AI_Movement_Track_Flush(kActorRunciter);
if (Random_Query(0, 1) == 1) {
if (Random_Query(0, 1) == 0) {
AI_Movement_Track_Append_With_Facing(kActorRunciter, 89, Random_Query(6, 10), 567);
}
AI_Movement_Track_Append_With_Facing(kActorRunciter, 93, Random_Query(2, 6), 1002);
AI_Movement_Track_Append(kActorRunciter, 92, 5);
} else {
AI_Movement_Track_Append_With_Facing(kActorRunciter, 91, Random_Query(3, 10), 120);
if (Random_Query(1, 3) == 1) {
AI_Movement_Track_Append_With_Facing(kActorRunciter, 93, Random_Query(2, 6), 1002);
}
AI_Movement_Track_Append_With_Facing(kActorRunciter, 90, Random_Query(5, 10), 170);
}
AI_Movement_Track_Repeat(kActorRunciter);
return true;
}
if (newGoalNumber == kGoalRunciterGoToFreeSlotGH) {
AI_Movement_Track_Flush(kActorRunciter);
AI_Movement_Track_Append(kActorRunciter, 39, 120);
AI_Movement_Track_Append(kActorRunciter, 40, 0);
AI_Movement_Track_Repeat(kActorRunciter);
return false;
}
if (newGoalNumber == kGoalRunciterRC02Wait) {
Actor_Put_In_Set(kActorRunciter, kSetRC02_RC51);
Actor_Set_At_Waypoint(kActorRunciter, 93, 1007);
return false;
}
return false;
}
bool AIScriptRunciter::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case kRunciterStateIdle:
if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationRunciterIdle;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
_animationFrame += var_45CD80;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterIdle)) {
_animationFrame = 0;
}
if (_animationFrame < 0) {
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterIdle) - 1;
}
--var_45CD7C;
if (var_45CD7C == 0) {
var_45CD80 = 2 * Random_Query(0, 1) - 1;
var_45CD7C = Random_Query(6, 14);
_varNumOfTimesToHoldCurrentFrame = Random_Query(0, 4);
}
if (_animationFrame == 0) {
if (Random_Query(0, 1) == 1) {
_varChooseIdleAnimation = Random_Query(1, 2);
var_45CD80 = 1;
_varNumOfTimesToHoldCurrentFrame = 0;
}
}
}
} else if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationRunciterScratchesWoundIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterScratchesWoundIdle)) {
_animationFrame = 0;
_varChooseIdleAnimation = 0;
*animation = kModelAnimationRunciterIdle;
var_45CD7C = Random_Query(6, 14);
var_45CD80 = 2 * Random_Query(0, 1) - 1;
}
} else if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationRunciterPicksNose;
if (_varNumOfTimesToHoldCurrentFrame > 0) {
--_varNumOfTimesToHoldCurrentFrame;
} else {
_animationFrame += var_45CD80;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation) - 1) {
_varNumOfTimesToHoldCurrentFrame = Random_Query(5, 15);
var_45CD80 = -1;
}
if (_animationFrame <= 0) {
_animationFrame = 0;
_varChooseIdleAnimation = 0;
*animation = kModelAnimationRunciterIdle;
var_45CD7C = Random_Query(6, 14);
var_45CD80 = 2 * Random_Query(0, 1) - 1;
}
}
}
*frame = _animationFrame;
break;
case kRunciterStateWalking:
*animation = kModelAnimationRunciterWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterWalking)) {
_animationFrame = 0;
}
*frame = _animationFrame;
break;
case 2:
*animation = kModelAnimationRunciterCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterCalmTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
_animationState = 4;
}
}
*frame = _animationFrame;
break;
case 4:
*animation = kModelAnimationRunciterSuggestOnTipToesTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterSuggestOnTipToesTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 5:
*animation = kModelAnimationRunciterExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterExplainTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 6:
*animation = kModelAnimationRunciterAngryTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterAngryTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 7:
*animation = kModelAnimationRunciterQuestionTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterQuestionTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 8:
*animation = kModelAnimationRunciterOffensiveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterOffensiveTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 9:
*animation = kModelAnimationRunciterComplainCryTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterComplainCryTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 10:
*animation = kModelAnimationRunciterDespairTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterDespairTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 11:
*animation = kModelAnimationRunciterCannotBelieveTalk;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterCannotBelieveTalk)) {
_animationFrame = 0;
if (var_45CD88 > 0) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_varChooseIdleAnimation = 0;
} else {
*animation = kModelAnimationRunciterCalmTalk;
_animationState = 2;
}
}
*frame = _animationFrame;
break;
case 12:
*animation = kModelAnimationRunciterGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterGestureGive)) {
*animation = kModelAnimationRunciterIdle;
_animationState = 0;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
Actor_Change_Animation_Mode(kActorRunciter, kAnimationModeCombatIdle);
}
*frame = _animationFrame;
break;
case 13:
if (_varChooseIdleAnimation == 0) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
} else if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationRunciterScratchesWoundIdle;
_animationFrame += 3;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterScratchesWoundIdle)) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
} else if (_varChooseIdleAnimation == 2) {
*animation = kModelAnimationRunciterPicksNose;
_animationFrame -= 3;
if (_animationFrame - 3 < 0) {
_animationFrame = 0;
_animationState = _animationStateNext;
*animation = _animationNext;
}
}
*frame = _animationFrame;
break;
case kRunciterStateDying:
*animation = kModelAnimationRunciterShotDead;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterShotDead) - 1) {
*animation = kModelAnimationRunciterShotDead;
_animationState = kRunciterStateDead;
}
*frame = _animationFrame;
break;
case kRunciterStateDead:
*animation = kModelAnimationRunciterShotDead;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationRunciterShotDead) - 1;
*frame = _animationFrame;
break;
default:
// Dummy placeholder, kModelAnimationZubenWalking (399) is a Zuben animation
*animation = kModelAnimationZubenWalking;
_animationFrame = 0;
*frame = _animationFrame;
debugC(6, kDebugAnimation, "AIScriptRunciter::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
return true;
}
bool AIScriptRunciter::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState >= 2 && _animationState <= 11) {
var_45CD88 = 1;
} else {
_animationState = 0;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
break;
case kAnimationModeWalk:
if (_animationState > 1) {
_animationState = 1;
_animationFrame = 0;
} else if (_animationState == 0) {
_animationState = 13;
_animationStateNext = 1;
_animationNext = kModelAnimationRunciterWalking;
}
break;
case kAnimationModeTalk:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 2;
_animationNext = kModelAnimationRunciterWalking;
}
var_45CD88 = 0;
break;
case 12:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 4;
_animationNext = kModelAnimationRunciterSuggestOnTipToesTalk;
}
var_45CD88 = 0;
break;
case 13:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 5;
_animationNext = kModelAnimationRunciterExplainTalk;
}
var_45CD88 = 0;
break;
case 14:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 6;
_animationNext = kModelAnimationRunciterAngryTalk;
}
var_45CD88 = 0;
break;
case 15:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 7;
_animationNext = kModelAnimationRunciterQuestionTalk;
}
var_45CD88 = 0;
break;
case 16:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 8;
_animationNext = kModelAnimationRunciterOffensiveTalk;
}
var_45CD88 = 0;
break;
case 17:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 9;
_animationNext = kModelAnimationRunciterComplainCryTalk;
}
var_45CD88 = 0;
break;
case 18:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 10;
_animationNext = kModelAnimationRunciterDespairTalk;
}
var_45CD88 = 0;
break;
case 19:
if (_animationState != 0) {
_animationState = 2;
_animationFrame = 0;
} else {
_animationState = 13;
_animationStateNext = 11;
_animationNext = kModelAnimationRunciterCannotBelieveTalk;
}
var_45CD88 = 0;
break;
case 23:
_animationState = 12;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 14;
_animationFrame = 0;
break;
}
return true;
}
void AIScriptRunciter::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptRunciter::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptRunciter::ReachedMovementTrackWaypoint(int waypointId) {
switch (waypointId) {
case 89:
Actor_Face_Heading(kActorRunciter, 567, true);
break;
case 90:
Actor_Face_Heading(kActorRunciter, 170, true);
break;
case 91:
Actor_Face_Heading(kActorRunciter, 120, true);
break;
case 92:
Actor_Face_Heading(kActorRunciter, 664, true);
break;
case 93:
Actor_Face_Heading(kActorRunciter, 1002, true);
break;
}
return true;
}
void AIScriptRunciter::FledCombat() {}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,524 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/bladerunner.h"
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptSebastian::AIScriptSebastian(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptSebastian::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Set_Goal_Number(kActorSebastian, 0);
}
bool AIScriptSebastian::Update() {
if (Actor_Query_Goal_Number(kActorSebastian) < 200
&& Global_Variable_Query(kVariableChapter) == 3
) {
Actor_Set_Goal_Number(kActorSebastian, 200);
}
return false;
}
void AIScriptSebastian::TimerExpired(int timer) {
//return false;
}
void AIScriptSebastian::CompletedMovementTrack() {
//return false;
}
void AIScriptSebastian::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptSebastian::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorSebastian) == 205) {
AI_Movement_Track_Pause(kActorSebastian);
Actor_Face_Actor(kActorSebastian, kActorMcCoy, true);
Actor_Face_Actor(kActorMcCoy, kActorSebastian, true);
if (Actor_Clue_Query(kActorSebastian, kClueMcCoyIsABladeRunner)) {
Actor_Says(kActorMcCoy, 6985, 16);
Actor_Says(kActorSebastian, 610, 14);
} else {
dialogue();
}
AI_Movement_Track_Unpause(kActorSebastian);
return; //true;
}
return; //false;
}
void AIScriptSebastian::EnteredSet(int setId) {
// return false;
}
void AIScriptSebastian::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptSebastian::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptSebastian::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
if (otherActorId == kActorMcCoy
&& combatMode
) {
#if BLADERUNNER_ORIGINAL_BUGS
Global_Variable_Increment(kVariableGunPulledInFrontOfSebastian, 1);
#else
// This is a minor fix: Prevent increasing the value of kVariableGunPulledInFrontOfSebastian without restriction
if (Global_Variable_Query(kVariableGunPulledInFrontOfSebastian) < 2) {
Global_Variable_Increment(kVariableGunPulledInFrontOfSebastian, 1);
}
#endif
Actor_Modify_Friendliness_To_Other(kActorSebastian, kActorMcCoy, -5);
AI_Movement_Track_Pause(kActorSebastian);
Actor_Face_Actor(kActorSebastian, kActorMcCoy, true);
if (Global_Variable_Query(kVariableGunPulledInFrontOfSebastian) == 1) {
Actor_Says(kActorSebastian, 680, 12);
Actor_Face_Actor(kActorMcCoy, kActorSebastian, true);
Actor_Says_With_Pause(kActorMcCoy, 7265, 0.0f, kAnimationModeCombatIdle);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeCombatIdle);
Delay(500);
Actor_Says(kActorSebastian, 690, 16);
} else {
Actor_Says(kActorSebastian, 700, 15);
Actor_Says_With_Pause(kActorMcCoy, 7270, 0.0f, kAnimationModeCombatIdle);
Actor_Change_Animation_Mode(kActorMcCoy, kAnimationModeCombatIdle);
}
AI_Movement_Track_Unpause(kActorSebastian);
return; //true;
}
}
void AIScriptSebastian::ShotAtAndMissed() {
// return false;
}
bool AIScriptSebastian::ShotAtAndHit() {
return false;
}
void AIScriptSebastian::Retired(int byActorId) {
// return false;
}
int AIScriptSebastian::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptSebastian::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 200) {
Actor_Put_In_Set(kActorSebastian, kSetBB05);
Actor_Set_At_XYZ(kActorSebastian, -13.08f, -60.31f, 100.88f, 470);
}
return false;
}
bool AIScriptSebastian::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationSebastianIdle;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianIdle) - 1) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationSebastianWalking;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianWalking) - 1) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationSebastianStepsBack;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianStepsBack) - 1) {
Actor_Change_Animation_Mode(kActorSebastian, kAnimationModeIdle);
*animation = kModelAnimationSebastianIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 3:
*animation = kModelAnimationSebastianTriesToRunHitsHeadAndFalls;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianTriesToRunHitsHeadAndFalls) - 1) {
++_animationFrame;
}
break;
case 4:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
Actor_Change_Animation_Mode(kActorSebastian, kAnimationModeIdle);
*animation = kModelAnimationSebastianIdle;
_animationState = 0;
_animationFrame = 0;
} else {
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianCalmHeadNodLeftTalk) - 1) {
_animationFrame = 0;
}
}
break;
case 5:
*animation = kModelAnimationSebastianCalmHeadNodRightTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianCalmHeadNodRightTalk) - 1) {
_animationFrame = 0;
_animationState = 4;
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
}
break;
case 6:
*animation = kModelAnimationSebastianSuggestTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianSuggestTalk) - 1) {
_animationFrame = 0;
_animationState = 4;
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
}
break;
case 7:
*animation = kModelAnimationSebastianWonderingTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianWonderingTalk) - 1) {
_animationFrame = 0;
_animationState = 4;
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
}
break;
case 8:
*animation = kModelAnimationSebastianPointingToSelfTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianPointingToSelfTalk) - 1) {
_animationFrame = 0;
_animationState = 4;
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
}
break;
case 9:
*animation = kModelAnimationSebastianScratchEarTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianScratchEarTalk) - 1) {
_animationFrame = 0;
_animationState = 4;
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
}
break;
case 10:
*animation = kModelAnimationSebastianAnnoyedTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianAnnoyedTalk) - 1) {
_animationFrame = 0;
_animationState = 4;
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
}
break;
case 11:
*animation = kModelAnimationSebastianWaitTalk;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationSebastianWaitTalk) - 1) {
_animationFrame = 0;
_animationState = 4;
*animation = kModelAnimationSebastianCalmHeadNodLeftTalk;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptSebastian::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptSebastian::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState > 11) {
_animationState = 0;
_animationFrame = 0;
} else {
_resumeIdleAfterFramesetCompletesFlag = true;
}
break;
case kAnimationModeWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 8;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 16:
_animationState = 9;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 17:
_animationState = 10;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 18:
_animationState = 11;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 20:
_animationState = 2;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 3;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptSebastian::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptSebastian::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptSebastian::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptSebastian::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptSebastian::FledCombat() {
// return false;
}
void AIScriptSebastian::dialogue() {
Dialogue_Menu_Clear_List();
if (Actor_Query_Friendliness_To_Other(kActorSebastian, kActorMcCoy) >= 45) {
DM_Add_To_List_Never_Repeat_Once_Selected(930, 5, 5, 5); // MORAJI AND CHEW
DM_Add_To_List_Never_Repeat_Once_Selected(940, -1, 5, 6); // EISENDULLER
DM_Add_To_List_Never_Repeat_Once_Selected(950, 5, 5, 5); // TYRELL
}
if (Actor_Clue_Query(kActorMcCoy, kClueAnsweringMachineMessage)) {
DM_Add_To_List_Never_Repeat_Once_Selected(960, 3, -1, 5); // TWINS
}
if (Actor_Clue_Query(kActorMcCoy, kClueAnsweringMachineMessage)
&& Actor_Clue_Query(kActorMcCoy, kClueEnvelope)
) {
DM_Add_To_List_Never_Repeat_Once_Selected(970, -1, 4, -1); // RUNCITER
}
DM_Add_To_List_Never_Repeat_Once_Selected(980, -1, -1, 7); // ROBBERS
DM_Add_To_List_Never_Repeat_Once_Selected(990, 7, 3, -1); // NEXUS-6
if (Dialogue_Menu_Query_List_Size()) {
// This condition clause for non-empty dialogue menu options before adding the DONE option
// only occurs in Sebastian's AI script.
// Probably because, selecting "DONE" here, McCoy has nothing to say
// so there's no point to add it as a "auto-selected" last option
// if no other options exist in the list
Dialogue_Menu_Add_DONE_To_List(1000); // DONE
Dialogue_Menu_Appear(320, 240);
int answer = Dialogue_Menu_Query_Input();
Dialogue_Menu_Disappear();
switch (answer) {
case 930: // MORAJI AND CHEW
Actor_Says(kActorMcCoy, 7075, 13);
Actor_Says(kActorSebastian, 290, 12);
Actor_Says(kActorSebastian, 300, 13);
break;
case 940: // EISENDULLER
Actor_Says(kActorMcCoy, 7080, 15);
Actor_Says(kActorSebastian, 310, 13);
Actor_Says(kActorSebastian, 320, 16);
Actor_Says(kActorSebastian, 340, 12);
Actor_Says(kActorMcCoy, 7120, 14);
Actor_Says(kActorSebastian, 350, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 7125, 13);
Actor_Says(kActorSebastian, 360, 17);
Actor_Says_With_Pause(kActorMcCoy, 7130, 1.0f, kAnimationModeTalk);
Actor_Says(kActorMcCoy, 7135, 18);
break;
case 950: // TYRELL
Actor_Says(kActorMcCoy, 7085, 15);
Actor_Says_With_Pause(kActorSebastian, 370, 0.30f, 13);
Actor_Says_With_Pause(kActorSebastian, 380, 0.70f, 17);
Actor_Says(kActorSebastian, 390, 14);
if (Actor_Clue_Query(kActorMcCoy, kClueChessTable)) {
Actor_Says(kActorMcCoy, 7140, kAnimationModeTalk);
Actor_Says(kActorSebastian, 400, 12);
Actor_Says(kActorMcCoy, 7145, 16);
Actor_Says(kActorSebastian, 410, 13);
Actor_Says(kActorMcCoy, 7150, 17);
Actor_Says(kActorSebastian, 420, 13);
Actor_Says(kActorSebastian, 430, 14);
}
break;
case 960: // TWINS
Actor_Says(kActorMcCoy, 7090, 17);
Actor_Says(kActorSebastian, 440, 14);
Actor_Says(kActorSebastian, 450, 13);
Actor_Says(kActorMcCoy, 7155, 13);
Actor_Says(kActorSebastian, 460, 17);
Actor_Says(kActorSebastian, 470, 12);
Actor_Says(kActorSebastian, 480, 13);
Actor_Says(kActorMcCoy, 7160, 18);
Actor_Says(kActorSebastian, 490, 14);
Actor_Says(kActorMcCoy, 7165, 14);
setMcCoyIsABladeRunner();
break;
case 970: // RUNCITER
Actor_Says(kActorMcCoy, 7095, 13);
Actor_Says(kActorSebastian, 500, 15);
Actor_Says(kActorMcCoy, 7170, 17);
Actor_Says(kActorSebastian, 510, 12);
Actor_Says(kActorMcCoy, 7175, 18);
Actor_Says(kActorSebastian, 520, 14);
Actor_Says(kActorMcCoy, 7180, 12);
Actor_Says(kActorSebastian, 530, 13);
Actor_Says(kActorMcCoy, 7185, 12);
setMcCoyIsABladeRunner();
break;
case 980: // ROBBERS
Actor_Says(kActorMcCoy, 7100, 12);
Actor_Says(kActorSebastian, 540, 16);
Actor_Says(kActorMcCoy, 7195, 18);
Actor_Says(kActorSebastian, 720, 12);
break;
case 990: // NEXUS-6
Actor_Says(kActorMcCoy, 7105, 18);
setMcCoyIsABladeRunner();
break;
default:
break;
}
} else if (Actor_Query_Friendliness_To_Other(kActorSebastian, kActorMcCoy) >= 45) {
Actor_Says(kActorMcCoy, 7115, 13);
Actor_Says(kActorSebastian, 280, 14);
} else {
Actor_Says(kActorMcCoy, 7110, 15);
Actor_Says(kActorSebastian, 270, 16);
}
}
void AIScriptSebastian::setMcCoyIsABladeRunner() {
Actor_Clue_Acquire(kActorSebastian, kClueMcCoyIsABladeRunner, true, kActorMcCoy);
Actor_Modify_Friendliness_To_Other(kActorSebastian, kActorMcCoy, -5);
Actor_Says(kActorSebastian, 560, 15);
Actor_Says(kActorMcCoy, 7200, 14);
Actor_Says(kActorSebastian, 570, 16);
Actor_Says(kActorMcCoy, 7205, 17);
Actor_Says(kActorSebastian, 580, 13);
Actor_Says_With_Pause(kActorMcCoy, 7210, 1.0f, 16);
Actor_Says(kActorSebastian, 590, 12);
Actor_Says(kActorMcCoy, 7215, 19);
Actor_Says(kActorSebastian, 600, 14);
Actor_Says(kActorMcCoy, 7220, 13);
Actor_Says_With_Pause(kActorMcCoy, 7225, 0.80f, 14);
Actor_Says(kActorSebastian, 610, 15);
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,282 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptSergeantWalls::AIScriptSergeantWalls(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptSergeantWalls::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptSergeantWalls::Update() {
if (Game_Flag_Query(kFlagSergeantWallsBuzzInRequest)
&& Game_Flag_Query(kFlagSergeantWallsBuzzInDone)
) {
Game_Flag_Reset(kFlagSergeantWallsBuzzInRequest);
}
return false;
}
void AIScriptSergeantWalls::TimerExpired(int timer) {
//return false;
}
void AIScriptSergeantWalls::CompletedMovementTrack() {
//return false;
}
void AIScriptSergeantWalls::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptSergeantWalls::ClickedByPlayer() {
//return false;
}
void AIScriptSergeantWalls::EnteredSet(int setId) {
// return false;
}
void AIScriptSergeantWalls::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptSergeantWalls::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptSergeantWalls::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptSergeantWalls::ShotAtAndMissed() {
// return false;
}
bool AIScriptSergeantWalls::ShotAtAndHit() {
return false;
}
void AIScriptSergeantWalls::Retired(int byActorId) {
// return false;
}
int AIScriptSergeantWalls::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptSergeantWalls::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptSergeantWalls::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
++_animationFrame;
if ( Game_Flag_Query(kFlagSergeantWallsBuzzInRequest)
&& !Game_Flag_Query(kFlagSergeantWallsBuzzInDone)
) {
// TODO maybe use kModelAnimationSergeantWallsHitsBuzzerTalk here?
*animation = kModelAnimationSergeantWallsGestureGive;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsGestureGive)) {
_animationFrame = 0;
Game_Flag_Set(kFlagSergeantWallsBuzzInDone);
}
} else {
*animation = kModelAnimationSergeantWallsIdle;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsIdle)) {
_animationFrame = 0;
}
}
break;
case 1:
*animation = kModelAnimationSergeantWallsCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsCalmTalk)) {
_animationFrame = 0;
}
break;
case 3:
*animation = kModelAnimationSergeantWallsMoreHeadMoveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsMoreHeadMoveTalk)) {
_animationState = 1;
_animationFrame = 0;
*animation = kModelAnimationSergeantWallsCalmTalk;
}
break;
case 4:
*animation = kModelAnimationSergeantWallsExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsExplainTalk)) {
_animationState = 1;
_animationFrame = 0;
*animation = kModelAnimationSergeantWallsCalmTalk;
}
break;
case 5:
*animation = kModelAnimationSergeantWallsLaughTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsLaughTalk)) {
_animationState = 1;
_animationFrame = 0;
*animation = kModelAnimationSergeantWallsCalmTalk;
}
break;
case 6:
*animation = kModelAnimationSergeantWallsHarderLaughTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsHarderLaughTalk)) {
_animationState = 1;
_animationFrame = 0;
*animation = kModelAnimationSergeantWallsCalmTalk;
}
break;
case 7:
*animation = kModelAnimationSergeantWallsDefendTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsDefendTalk)) {
_animationState = 1;
_animationFrame = 0;
*animation = kModelAnimationSergeantWallsCalmTalk;
}
break;
case 8:
*animation = kModelAnimationSergeantWallsHitsBuzzerTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsHitsBuzzerTalk)) {
_animationState = 1;
_animationFrame = 0;
*animation = kModelAnimationSergeantWallsCalmTalk;
}
break;
case 9:
*animation = kModelAnimationSergeantWallsGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationSergeantWallsGestureGive)) {
_animationState = 9;
_animationFrame = 0;
*animation = kModelAnimationSergeantWallsGestureGive;
}
break;
default:
// Dummy placeholder, kModelAnimationZubenWalking (399) is a Zuben animation
*animation = kModelAnimationZubenWalking;
debugC(6, kDebugAnimation, "AIScriptSergeantWalls::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptSergeantWalls::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 1;
_animationFrame = 0;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
break;
case 16:
_animationState = 7;
_animationFrame = 0;
break;
case 17:
_animationState = 8;
_animationFrame = 0;
break;
case 23:
_animationState = 9;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptSergeantWalls::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptSergeantWalls::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptSergeantWalls::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptSergeantWalls::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptSergeantWalls::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,219 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptShoeshineMan::AIScriptShoeshineMan(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_state = false;
}
void AIScriptShoeshineMan::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_state = false;
}
bool AIScriptShoeshineMan::Update() {
return false;
}
void AIScriptShoeshineMan::TimerExpired(int timer) {
//return false;
}
void AIScriptShoeshineMan::CompletedMovementTrack() {
//return false;
}
void AIScriptShoeshineMan::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptShoeshineMan::ClickedByPlayer() {
if (Actor_Query_Goal_Number(kActorShoeshineMan) != 100) {
return;
}
if (!Loop_Actor_Walk_To_XYZ(kActorMcCoy, -1098.15f, -0.04f, -201.53f, 0, true, false, false)) {
Actor_Set_Goal_Number(kActorShoeshineMan, 102);
Actor_Face_Actor(kActorMcCoy, kActorShoeshineMan, true);
Actor_Says_With_Pause(kActorShoeshineMan, 0, 1.2f, 13);
Actor_Says(kActorMcCoy, 730, 17);
Actor_Says(kActorShoeshineMan, 10, 13);
Actor_Says(kActorShoeshineMan, 20, 12);
Actor_Says_With_Pause(kActorMcCoy, 735, 1.0f, 14);
Actor_Change_Animation_Mode(kActorShoeshineMan, 29);
}
}
void AIScriptShoeshineMan::EnteredSet(int setId) {
// return false;
}
void AIScriptShoeshineMan::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptShoeshineMan::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptShoeshineMan::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptShoeshineMan::ShotAtAndMissed() {
// return false;
}
bool AIScriptShoeshineMan::ShotAtAndHit() {
return false;
}
void AIScriptShoeshineMan::Retired(int byActorId) {
// return false;
}
int AIScriptShoeshineMan::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptShoeshineMan::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 100:
Actor_Put_In_Set(kActorShoeshineMan, kSetDR01_DR02_DR04);
Actor_Set_At_XYZ(kActorShoeshineMan, -1160.0f, -0.04f, -235.0f, 524);
break;
case 101:
AI_Movement_Track_Flush(kActorShoeshineMan);
AI_Movement_Track_Append(kActorShoeshineMan, 281, 0);
AI_Movement_Track_Append(kActorShoeshineMan, 40, 0);
AI_Movement_Track_Repeat(kActorShoeshineMan);
break;
}
return false;
}
bool AIScriptShoeshineMan::UpdateAnimation(int *animation, int *frame) {
switch(_animationState) {
case 0:
// fall through
case 1:
// fall through
case 2:
// fall through
case 3:
// fall through
case 4:
// fall through
case 5:
// fall through
case 6:
break;
default:
debugC(6, kDebugAnimation, "AIScriptShoeshineMan::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
return true;
}
bool AIScriptShoeshineMan::ChangeAnimationMode(int mode) {
switch (mode) {
case 0:
if (_animationState >= 2 && _animationState <= 4) {
_state = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case 1:
_animationState = 1;
_animationFrame = 0;
break;
case 3:
_animationState = 2;
_animationFrame = 0;
_state = false;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
_state = false;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
_state = false;
break;
case 23:
_animationState = 5;
_animationFrame = 0;
break;
case 29:
_animationState = 6;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptShoeshineMan::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptShoeshineMan::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptShoeshineMan::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptShoeshineMan::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptShoeshineMan::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTaffy::AIScriptTaffy(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptTaffy::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptTaffy::Update() {
return false;
}
void AIScriptTaffy::TimerExpired(int timer) {
//return false;
}
void AIScriptTaffy::CompletedMovementTrack() {
//return false;
}
void AIScriptTaffy::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTaffy::ClickedByPlayer() {
//return false;
}
void AIScriptTaffy::EnteredSet(int setId) {
// return false;
}
void AIScriptTaffy::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptTaffy::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptTaffy::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTaffy::ShotAtAndMissed() {
// return false;
}
bool AIScriptTaffy::ShotAtAndHit() {
return false;
}
void AIScriptTaffy::Retired(int byActorId) {
// return false;
}
int AIScriptTaffy::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTaffy::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptTaffy::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptTaffy::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptTaffy::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTaffy::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTaffy::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTaffy::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,193 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTaffyPatron::AIScriptTaffyPatron(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptTaffyPatron::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptTaffyPatron::Update() {
return false;
}
void AIScriptTaffyPatron::TimerExpired(int timer) {
//return false;
}
void AIScriptTaffyPatron::CompletedMovementTrack() {
//return false;
}
void AIScriptTaffyPatron::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTaffyPatron::ClickedByPlayer() {
//return false;
}
void AIScriptTaffyPatron::EnteredSet(int setId) {
// return false;
}
void AIScriptTaffyPatron::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptTaffyPatron::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptTaffyPatron::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTaffyPatron::ShotAtAndMissed() {
// return false;
}
bool AIScriptTaffyPatron::ShotAtAndHit() {
return false;
}
void AIScriptTaffyPatron::Retired(int byActorId) {
// return false;
}
int AIScriptTaffyPatron::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTaffyPatron::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case 0:
Actor_Put_In_Set(kActorTaffyPatron, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorTaffyPatron, 40, 0);
return true;
case 250:
Actor_Put_In_Set(kActorTaffyPatron, kSetNR01);
Actor_Set_At_XYZ(kActorTaffyPatron, -170.4f, 23.68f, -850.0f, 324);
Async_Actor_Walk_To_XYZ(kActorTaffyPatron, -390.0f, 31.55f, -429.0f, 24, true);
return true;
case 255:
Actor_Put_In_Set(kActorTaffyPatron, kSetNR01);
Actor_Set_At_XYZ(kActorTaffyPatron, -170.4f, 23.68f, -850.0f, 324);
Actor_Change_Animation_Mode(kActorTaffyPatron, 48);
return true;
default:
break;
}
return false;
}
bool AIScriptTaffyPatron::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
// Dummy placeholder, kModelAnimationZubenIdle (406) is a Zuben animation
*animation = kModelAnimationZubenIdle;
_animationFrame = 0;
break;
case 1:
*animation = kModelAnimationTaffyPatronRunning;
++_animationFrame;
if (_animationFrame > Slice_Animation_Query_Number_Of_Frames(kModelAnimationTaffyPatronRunning) - 1) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationTaffyPatronShotDead;
if (_animationFrame < Slice_Animation_Query_Number_Of_Frames(kModelAnimationTaffyPatronShotDead) - 1) {
++_animationFrame;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptTaffyPatron::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptTaffyPatron::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
_animationState = 0;
_animationFrame = 0;
break;
case kAnimationModeRun:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeDie:
_animationState = 2;
_animationFrame = 0;
break;
default:
debugC(6, kDebugAnimation, "AIScriptTaffyPatron::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptTaffyPatron::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTaffyPatron::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTaffyPatron::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTaffyPatron::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTeenager::AIScriptTeenager(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptTeenager::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptTeenager::Update() {
return false;
}
void AIScriptTeenager::TimerExpired(int timer) {
//return false;
}
void AIScriptTeenager::CompletedMovementTrack() {
//return false;
}
void AIScriptTeenager::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTeenager::ClickedByPlayer() {
//return false;
}
void AIScriptTeenager::EnteredSet(int setId) {
// return false;
}
void AIScriptTeenager::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptTeenager::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptTeenager::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTeenager::ShotAtAndMissed() {
// return false;
}
bool AIScriptTeenager::ShotAtAndHit() {
return false;
}
void AIScriptTeenager::Retired(int byActorId) {
// return false;
}
int AIScriptTeenager::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTeenager::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptTeenager::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptTeenager::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptTeenager::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTeenager::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTeenager::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTeenager::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,122 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTheBard::AIScriptTheBard(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptTheBard::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
}
bool AIScriptTheBard::Update() {
return false;
}
void AIScriptTheBard::TimerExpired(int timer) {
//return false;
}
void AIScriptTheBard::CompletedMovementTrack() {
//return false;
}
void AIScriptTheBard::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTheBard::ClickedByPlayer() {
//return false;
}
void AIScriptTheBard::EnteredSet(int setId) {
// return false;
}
void AIScriptTheBard::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptTheBard::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptTheBard::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTheBard::ShotAtAndMissed() {
// return false;
}
bool AIScriptTheBard::ShotAtAndHit() {
return false;
}
void AIScriptTheBard::Retired(int byActorId) {
// return false;
}
int AIScriptTheBard::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTheBard::GoalChanged(int currentGoalNumber, int newGoalNumber) {
return false;
}
bool AIScriptTheBard::UpdateAnimation(int *animation, int *frame) {
return true;
}
bool AIScriptTheBard::ChangeAnimationMode(int mode) {
return true;
}
void AIScriptTheBard::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTheBard::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTheBard::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTheBard::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,580 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTransient::AIScriptTransient(BladeRunnerEngine *vm) : AIScriptBase(vm) {
}
void AIScriptTransient::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
Actor_Put_In_Set(kActorTransient, kSetCT03_CT04);
Actor_Set_At_XYZ(kActorTransient, -171.41f, -621.3f, 736.52f, 580);
Actor_Set_Goal_Number(kActorTransient, kGoalTransientDefault);
Actor_Set_Targetable(kActorTransient, true);
}
bool AIScriptTransient::Update() {
if (Global_Variable_Query(kVariableChapter) == 5
&& Actor_Query_Which_Set_In(kActorTransient) != kSetFreeSlotG
) {
Actor_Put_In_Set(kActorTransient, kSetFreeSlotG);
Actor_Set_At_Waypoint(kActorTransient, 39, false);
}
if (Global_Variable_Query(kVariableChapter) == 2
&& (Actor_Query_Goal_Number(kActorTransient) == kGoalTransientDefault
|| Actor_Query_Goal_Number(kActorTransient) == 10
)
) {
Actor_Set_Goal_Number(kActorTransient, 200);
}
if ( Global_Variable_Query(kVariableChapter) == 3
&& Game_Flag_Query(kFlagCT04HomelessKilledByMcCoy)
&& Game_Flag_Query(kFlagCT04HomelessBodyInDumpster)
&& !Game_Flag_Query(kFlagCT04HomelessBodyFound)
&& !Game_Flag_Query(kFlagCT04HomelessBodyThrownAway)
) {
Game_Flag_Set(kFlagCT04HomelessBodyThrownAway);
}
if (Global_Variable_Query(kVariableChapter) < 4
&& Game_Flag_Query(kFlagCT04HomelessBodyFound)
&& Actor_Query_Goal_Number(kActorTransient) != 6
&& Actor_Query_Goal_Number(kActorTransient) != 599
) {
Actor_Set_Goal_Number(kActorTransient, 6);
}
if ( Player_Query_Current_Scene() == kSceneCT04
&& !Game_Flag_Query(kFlagCT04HomelessTrashFinish)
) {
Game_Flag_Set(kFlagCT04HomelessTrashFinish);
AI_Countdown_Timer_Reset(kActorTransient, kActorTimerAIScriptCustomTask1);
AI_Countdown_Timer_Start(kActorTransient, kActorTimerAIScriptCustomTask1, 12);
}
return false;
}
void AIScriptTransient::TimerExpired(int timer) {
if (timer == kActorTimerAIScriptCustomTask0) {
if (Actor_Query_Goal_Number(kActorTransient) == 395 && Actor_Query_Which_Set_In(kActorMcCoy) == kSetUG13) {
AI_Countdown_Timer_Start(kActorTransient, kActorTimerAIScriptCustomTask0, Random_Query(20, 10));
switch (Random_Query(1, 3)) {
case 1:
Sound_Play(kSfxBUMSNOR1, 50, 0, 0, 50);
break;
case 2:
Sound_Play(kSfxBUMSNOR2, 50, 0, 0, 50);
break;
case 3:
Sound_Play(kSfxBUMSNOR3, 50, 0, 0, 50);
break;
}
} else if (Actor_Query_Goal_Number(kActorTransient) != 599) {
Actor_Set_Goal_Number(kActorTransient, 391);
AI_Countdown_Timer_Reset(kActorTransient, kActorTimerAIScriptCustomTask0);
}
}
if (timer == kActorTimerAIScriptCustomTask1) {
if (Actor_Query_Goal_Number(kActorTransient) == kGoalTransientDefault) { // stop diggin the trash
Actor_Set_Goal_Number(kActorTransient, 10);
Actor_Change_Animation_Mode(kActorTransient, kAnimationModeIdle);
}
Actor_Set_Goal_Number(kActorTransient, 10);
Actor_Set_Targetable(kActorTransient, false);
AI_Countdown_Timer_Reset(kActorTransient, kActorTimerAIScriptCustomTask1);
}
}
void AIScriptTransient::CompletedMovementTrack() {
//return false;
}
void AIScriptTransient::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTransient::ClickedByPlayer() {
//return false;
}
void AIScriptTransient::EnteredSet(int setId) {
// return false;
}
void AIScriptTransient::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptTransient::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptTransient::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTransient::ShotAtAndMissed() {
// return false;
}
bool AIScriptTransient::ShotAtAndHit() {
Actor_Set_Frame_Rate_FPS(kActorTransient, 8);
if (Game_Flag_Query(kFlagUG13HomelessLayingdown)) {
_animationState = 11;
} else {
_animationState = 14;
}
_animationFrame = 0;
Actor_Set_Targetable(kActorTransient, false);
if (Global_Variable_Query(kVariableChapter) < 4) {
Actor_Set_Goal_Number(kActorTransient, 3);
} else {
Actor_Set_Goal_Number(kActorTransient, 599);
}
Game_Flag_Set(kFlagCT04HomelessKilledByMcCoy);
return false;
}
void AIScriptTransient::Retired(int byActorId) {
Actor_Set_Goal_Number(kActorTransient, 599);
if (Global_Variable_Query(kVariableChapter) == 4) {
Game_Flag_Set(kFlagMcCoyRetiredHuman);
}
}
int AIScriptTransient::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTransient::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalTransientCT04Leave:
AI_Movement_Track_Flush(kActorTransient);
AI_Movement_Track_Append(kActorTransient, 51, 0);
AI_Movement_Track_Append(kActorTransient, 105, 0);
AI_Movement_Track_Append(kActorTransient, 42, 1);
AI_Movement_Track_Repeat(kActorTransient);
return true;
case 6:
AI_Movement_Track_Flush(kActorTransient);
AI_Movement_Track_Append(kActorTransient, 41, 10);
AI_Movement_Track_Repeat(kActorTransient);
return true;
case 200:
Actor_Put_In_Set(kActorTransient, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorTransient, 40, 0);
return true;
case 390:
// laying on the couch - not sleeping
Actor_Put_In_Set(kActorTransient, kSetUG13);
Actor_Set_At_XYZ(kActorTransient, -310.0, 55.0, -350.0, 400);
Actor_Change_Animation_Mode(kActorTransient, 53);
Actor_Set_Targetable(kActorTransient, true);
Game_Flag_Set(kFlagUG13HomelessLayingdown);
return true;
case 391:
// laying on the couch - sleeping - dialogue exhausted pre-flask - awaiting flask
Actor_Change_Animation_Mode(kActorTransient, 53);
return true;
case 395:
// laying on the couch - sleeping - post flask
Actor_Change_Animation_Mode(kActorTransient, 55);
AI_Countdown_Timer_Start(kActorTransient, kActorTimerAIScriptCustomTask0, Random_Query(30, 40));
return true;
case 599:
AI_Countdown_Timer_Reset(kActorTransient, kActorTimerAIScriptCustomTask0);
return true;
}
return false;
}
bool AIScriptTransient::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationTransientPickingNodeAndWiping;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientPickingNodeAndWiping)) {
_animationFrame = 0;
} else {
*animation = kModelAnimationTransientIdle;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientIdle)) {
_animationFrame = 0;
}
}
break;
case 1:
*animation = kModelAnimationTransientWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientWalking)) {
_animationFrame = 0;
}
break;
case 2:
*animation = kModelAnimationTransientGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientGestureGive)) {
_animationFrame = 0;
}
break;
case 3:
*animation = kModelAnimationTransientScratchBackOfHeadTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientScratchBackOfHeadTalk)) {
*animation = kModelAnimationTransientGestureGive;
_animationState = 2;
_animationFrame = 0;
}
break;
case 4:
*animation = kModelAnimationTransientDescriptiveTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientDescriptiveTalk)) {
*animation = kModelAnimationTransientGestureGive;
_animationState = 2;
_animationFrame = 0;
}
break;
case 5:
*animation = kModelAnimationTransientPointingAtTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientPointingAtTalk)) {
*animation = kModelAnimationTransientGestureGive;
_animationState = 2;
_animationFrame = 0;
}
break;
case 6:
*animation = kModelAnimationTransientLayingIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingIdle)) {
_animationFrame = 0;
}
break;
case 7:
*animation = kModelAnimationTransientLayingCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingCalmTalk)) {
_animationState = 6;
_animationFrame = 0;
}
break;
case 8:
*animation = kModelAnimationTransientLayingMoreCalmTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingMoreCalmTalk)) {
_animationState = 6;
_animationFrame = 0;
}
break;
case 9:
*animation = kModelAnimationTransientLayingThisAndThatTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingThisAndThatTalk)) {
_animationState = 6;
_animationFrame = 0;
}
break;
case 10:
*animation = kModelAnimationTransientLayingGestureGiveOrTake;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingGestureGiveOrTake)) {
_animationState = 6;
_animationFrame = 0;
}
break;
case 11:
*animation = kModelAnimationTransientLayingShotDead;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingShotDead)) {
Actor_Set_Frame_Rate_FPS(kActorTransient, 8);
_animationState = 12;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingShotDead) - 1;
}
break;
case 12:
*animation = kModelAnimationTransientLayingShotDead;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingShotDead) - 1;
break;
case 14:
*animation = kModelAnimationTransientShotDeadCollapseInPlace;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientShotDeadCollapseInPlace)) {
Actor_Set_Goal_Number(kActorTransient, 3);
_animationState = 15;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientShotDeadCollapseInPlace) - 1;
Actor_Set_Targetable(kActorTransient, false);
Actor_Retired_Here(kActorTransient, 120, 24, true, -1);
}
break;
case 15:
*animation = kModelAnimationTransientShotDeadCollapseInPlace;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientShotDeadCollapseInPlace) - 1;
break;
case 16:
*animation = kModelAnimationTransientSearchingTrash;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientSearchingTrash) - 1) {
_animationFrame = 0;
}
break;
case 17:
*animation = kModelAnimationTransientSearchingTrashToIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientSearchingTrashToIdle) - 1) {
*animation = kModelAnimationTransientIdle;
_animationFrame = 0;
_animationState = 0;
Actor_Change_Animation_Mode(kActorTransient, kAnimationModeIdle);
if (Actor_Query_Goal_Number(kActorTransient) == 10 && Player_Query_Current_Scene() == kSceneCT04) {
Actor_Set_At_XYZ(kActorTransient, -171.41f, -621.30f, 728.52f, 530);
Actor_Face_Actor(kActorTransient, kActorMcCoy, true);
}
}
break;
case 18:
*animation = kModelAnimationTransientLayingIdle;
++_animationFrame;
if (_animationFrame - 1 == 4) {
_animationState = 19;
}
break;
case 19:
*animation = kModelAnimationTransientLayingIdle;
--_animationFrame;
if (_animationFrame + 1 == 4) {
_animationState = 18;
}
break;
default:
// Dummy placeholder, kModelAnimationZubenWalking (399) is a Zuben animation
*animation = kModelAnimationZubenWalking;
debugC(6, kDebugAnimation, "AIScriptTransient::UpdateAnimation() - Current _animationState (%d) is a placeholder", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptTransient::ChangeAnimationMode(int mode) {
if (mode != 55) {
Actor_Set_Frame_Rate_FPS(kActorTransient, 8);
}
switch (mode) {
case 0:
switch (_animationState) {
case 0:
break;
case 6:
// fall through
case 7:
// fall through
case 8:
// fall through
case 9:
// fall through
case 10:
// fall through
case 18:
// fall through
case 19:
_animationState = 6;
_animationFrame = 0;
break;
case 16:
_animationState = 17;
_animationFrame = 0;
break;
default:
_animationState = 0;
_animationFrame = 0;
break;
}
break;
case 1:
if (_animationState != 1) {
_animationState = 1;
_animationFrame = 0;
}
break;
case 3:
// fall through
case 30:
if (_animationState - 6 > 4) {
_animationState = 2;
} else {
_animationState = 7;
}
_animationFrame = 0;
break;
case 12:
// fall through
case 31:
if (_animationState == 6) {
_animationState = 8;
} else {
_animationState = 3;
}
_animationFrame = 0;
break;
case 13:
// fall through
case 32:
if (_animationState == 6) {
_animationState = 9;
} else {
_animationState = 4;
}
_animationFrame = 0;
break;
case 14:
// fall through
case 33:
// fall through
case 34:
// fall through
case 35:
// fall through
case 36:
// fall through
case 37:
if (_animationState == 6) {
_animationState = 10;
} else {
_animationState = 5;
}
_animationFrame = 0;
break;
case 21:
if (Game_Flag_Query(kFlagUG13HomelessLayingdown)) {
_animationState = 11;
} else {
_animationState = 14;
}
_animationFrame = 0;
break;
case 38:
_animationState = 16;
_animationFrame = 0;
break;
case 53:
// fall through
case 54:
_animationState = 6;
_animationFrame = 0;
break;
case 55:
if (_animationState == 6) {
Actor_Set_Frame_Rate_FPS(kActorTransient, 4);
_animationState = 18;
_animationFrame = 3;
}
break;
case 89:
_animationState = 12;
_animationFrame = Slice_Animation_Query_Number_Of_Frames(kModelAnimationTransientLayingShotDead) - 1;
break;
default:
debugC(6, kDebugAnimation, "AIScriptTransient::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptTransient::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTransient::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTransient::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTransient::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,277 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTyrell::AIScriptTyrell(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_resumeIdleAfterFramesetCompletesFlag = true;
// _varChooseIdleAnimation can have valid values: 0, 1
_varChooseIdleAnimation = 0;
}
void AIScriptTyrell::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_resumeIdleAfterFramesetCompletesFlag = true;
_varChooseIdleAnimation = 0;
Actor_Set_Goal_Number(kActorTyrell, 0);
}
bool AIScriptTyrell::Update() {
if (Global_Variable_Query(kVariableChapter) > 3 && Actor_Query_Goal_Number(kActorTyrell) < 300)
Actor_Set_Goal_Number(kActorTyrell, 300);
return false;
}
void AIScriptTyrell::TimerExpired(int timer) {
//return false;
}
void AIScriptTyrell::CompletedMovementTrack() {
//return false;
}
void AIScriptTyrell::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTyrell::ClickedByPlayer() {
//return false;
}
void AIScriptTyrell::EnteredSet(int setId) {
// return false;
}
void AIScriptTyrell::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptTyrell::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptTyrell::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTyrell::ShotAtAndMissed() {
// return false;
}
bool AIScriptTyrell::ShotAtAndHit() {
return false;
}
void AIScriptTyrell::Retired(int byActorId) {
// return false;
}
int AIScriptTyrell::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTyrell::GoalChanged(int currentGoalNumber, int newGoalNumber) {
if (newGoalNumber == 300) {
Actor_Put_In_Set(kActorTyrell, kSetFreeSlotH);
Actor_Set_At_Waypoint(kActorTyrell, 40, 0);
}
return false;
}
bool AIScriptTyrell::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
if (_varChooseIdleAnimation == 1) {
*animation = kModelAnimationTyrellHeadMoveIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellHeadMoveIdle)) {
*animation = kModelAnimationTyrellIdle;
_animationFrame = 0;
_varChooseIdleAnimation = 0;
}
} else if (_varChooseIdleAnimation == 0) {
*animation = kModelAnimationTyrellIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellIdle)) {
_animationFrame = 0;
if (!Random_Query(0, 3)) {
_varChooseIdleAnimation = 1;
}
}
}
break;
case 1:
*animation = kModelAnimationTyrellWalking;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellWalking)) {
_animationFrame = 0;
}
break;
case 2:
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationTyrellIdle;
_animationState = 0;
} else {
*animation = kModelAnimationTyrellFastNodTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellFastNodTalk)) {
_animationFrame = 0;
}
}
break;
case 3:
*animation = kModelAnimationTyrellSuggestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellSuggestTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTyrellFastNodTalk;
}
break;
case 4:
*animation = kModelAnimationTyrellConsideringTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellConsideringTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTyrellFastNodTalk;
}
break;
case 5:
*animation = kModelAnimationTyrellBowsAndSuggestsTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellBowsAndSuggestsTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTyrellFastNodTalk;
}
break;
case 6:
*animation = kModelAnimationTyrellDismissTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellDismissTalk)) {
_animationFrame = 0;
_animationState = 2;
*animation = kModelAnimationTyrellFastNodTalk;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptTyrell::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptTyrell::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
if (_animationState >= 2 && _animationState <= 6) {
_resumeIdleAfterFramesetCompletesFlag = true;
} else {
_animationState = 0;
_animationFrame = 0;
}
break;
case kAnimationModeWalk:
_animationState = 1;
_animationFrame = 0;
break;
case kAnimationModeTalk:
_animationState = 2;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 12:
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 13:
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 14:
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
case 15:
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
break;
default:
debugC(6, kDebugAnimation, "AIScriptTyrell::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptTyrell::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTyrell::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTyrell::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTyrell::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

View File

@@ -0,0 +1,411 @@
/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "bladerunner/script/ai_script.h"
namespace BladeRunner {
AIScriptTyrellGuard::AIScriptTyrellGuard(BladeRunnerEngine *vm) : AIScriptBase(vm) {
_frameDelta = 1;
_resumeIdleAfterFramesetCompletesFlag = false;
}
void AIScriptTyrellGuard::Initialize() {
_animationFrame = 0;
_animationState = 0;
_animationStateNext = 0;
_animationNext = 0;
_frameDelta = 1;
_resumeIdleAfterFramesetCompletesFlag = false;
Actor_Set_Goal_Number(kActorTyrellGuard, 0);
}
bool AIScriptTyrellGuard::Update() {
return false;
}
void AIScriptTyrellGuard::TimerExpired(int timer) {
switch (timer) {
case kActorTimerAIScriptCustomTask0:
AI_Countdown_Timer_Reset(kActorTyrellGuard, kActorTimerAIScriptCustomTask0);
if (Actor_Query_Which_Set_In(kActorMcCoy) == kSetTB02_TB03) {
Actor_Set_Goal_Number(kActorTyrellGuard, kGoalTyrellGuardWakeUpAndArrestMcCoy);
}
break;
case kActorTimerAIScriptCustomTask1:
AI_Countdown_Timer_Reset(kActorTyrellGuard, kActorTimerAIScriptCustomTask1);
Actor_Set_Goal_Number(kActorTyrellGuard, kGoalTyrellGuardArrestMcCoy);
break;
}
}
void AIScriptTyrellGuard::CompletedMovementTrack() {
//return false;
}
void AIScriptTyrellGuard::ReceivedClue(int clueId, int fromActorId) {
//return false;
}
void AIScriptTyrellGuard::ClickedByPlayer() {
//return false;
}
void AIScriptTyrellGuard::EnteredSet(int setId) {
// return false;
}
void AIScriptTyrellGuard::OtherAgentEnteredThisSet(int otherActorId) {
// return false;
}
void AIScriptTyrellGuard::OtherAgentExitedThisSet(int otherActorId) {
// return false;
}
void AIScriptTyrellGuard::OtherAgentEnteredCombatMode(int otherActorId, int combatMode) {
// return false;
}
void AIScriptTyrellGuard::ShotAtAndMissed() {
// return false;
}
bool AIScriptTyrellGuard::ShotAtAndHit() {
return false;
}
void AIScriptTyrellGuard::Retired(int byActorId) {
// return false;
}
int AIScriptTyrellGuard::GetFriendlinessModifierIfGetsClue(int otherActorId, int clueId) {
return 0;
}
bool AIScriptTyrellGuard::GoalChanged(int currentGoalNumber, int newGoalNumber) {
switch (newGoalNumber) {
case kGoalTyrellGuardSleeping:
if (currentGoalNumber != newGoalNumber) {
Actor_Change_Animation_Mode(kActorTyrellGuard, 55);
AI_Countdown_Timer_Start(kActorTyrellGuard, kActorTimerAIScriptCustomTask0, 30);
}
return true;
case kGoalTyrellGuardWakeUpAndArrestMcCoy:
Actor_Change_Animation_Mode(kActorTyrellGuard, kAnimationModeIdle);
Delay(1000);
Actor_Says(kActorTyrellGuard, 320, 14);
Actor_Change_Animation_Mode(kActorTyrellGuard, 50);
Ambient_Sounds_Play_Sound(kSfxTBALARM, 100, 0, 0, 0);
Delay(1000);
Actor_Force_Stop_Walking(kActorMcCoy);
Actor_Set_Goal_Number(kActorMcCoy, kGoalMcCoyArrested);
return true;
case kGoalTyrellGuardWakeUp:
AI_Countdown_Timer_Reset(kActorTyrellGuard, kActorTimerAIScriptCustomTask0);
Actor_Says(kActorTyrellGuard, 310, 14);
AI_Countdown_Timer_Start(kActorTyrellGuard, kActorTimerAIScriptCustomTask1, 20);
return true;
case kGoalTyrellGuardArrestMcCoy:
Actor_Change_Animation_Mode(kActorTyrellGuard, 50);
Ambient_Sounds_Play_Sound(kSfxTBALARM, 100, 0, 0, 0);
Delay(1000);
Actor_Force_Stop_Walking(kActorMcCoy);
Actor_Set_Goal_Number(kActorMcCoy, kGoalMcCoyArrested);
return true;
case kGoalTyrellGuardWait:
AI_Countdown_Timer_Reset(kActorTyrellGuard, kActorTimerAIScriptCustomTask1);
return true;
}
return false;
}
bool AIScriptTyrellGuard::UpdateAnimation(int *animation, int *frame) {
switch (_animationState) {
case 0:
*animation = kModelAnimationTyrellGuardSittingIdle;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingIdle)) {
_animationFrame = 0;
}
break;
case 1:
*animation = kModelAnimationTyrellGuardSittingSleepingWakingUp;
if (_animationFrame <= 5) {
_frameDelta = 1;
} else if (_animationFrame >= 12) {
_frameDelta = -1;
}
_animationFrame += _frameDelta;
break;
case 2:
*animation = kModelAnimationTyrellGuardSittingSleepingWakingUp;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingSleepingWakingUp)) {
_animationFrame = 0;
_animationState = 0;
}
break;
case 3:
*animation = kModelAnimationTyrellGuardSittingCalmTalk;
if (_animationFrame == 0 && _resumeIdleAfterFramesetCompletesFlag) {
*animation = kModelAnimationTyrellGuardSittingIdle;
_animationState = 0;
} else {
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(*animation)) {
_animationFrame = 0;
}
}
break;
case 4:
*animation = kModelAnimationTyrellGuardSittingExplainTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingExplainTalk)) {
*animation = kModelAnimationTyrellGuardSittingCalmTalk;
_animationFrame = 0;
_animationState = 3;
}
break;
case 5:
*animation = kModelAnimationTyrellGuardSittingHandOverHeadTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingHandOverHeadTalk)) {
*animation = kModelAnimationTyrellGuardSittingCalmTalk;
_animationFrame = 0;
_animationState = 3;
}
break;
case 6:
*animation = kModelAnimationTyrellGuardSittingSuggestTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingSuggestTalk)) {
*animation = kModelAnimationTyrellGuardSittingCalmTalk;
_animationFrame = 0;
_animationState = 3;
}
break;
case 7:
*animation = kModelAnimationTyrellGuardSittingUpsetTalk;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingUpsetTalk)) {
*animation = kModelAnimationTyrellGuardSittingCalmTalk;
_animationFrame = 0;
_animationState = 3;
}
break;
case 8:
*animation = kModelAnimationTyrellGuardSittingGestureGive;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingGestureGive)) {
*animation = kModelAnimationTyrellGuardSittingIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 9:
*animation = kModelAnimationTyrellGuardSittingMaybeHugsMonitors;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingMaybeHugsMonitors)) {
*animation = kModelAnimationTyrellGuardSittingIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 10:
*animation = kModelAnimationTyrellGuardSittingSleepingWakingUp;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingSleepingWakingUp)) {
*animation = kModelAnimationTyrellGuardSittingIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
case 11:
*animation = kModelAnimationTyrellGuardSittingPressingAlertButton;
++_animationFrame;
if (_animationFrame >= Slice_Animation_Query_Number_Of_Frames(kModelAnimationTyrellGuardSittingPressingAlertButton)) {
*animation = kModelAnimationTyrellGuardSittingIdle;
_animationFrame = 0;
_animationState = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptTyrellGuard::UpdateAnimation() - Current _animationState (%d) is not supported", _animationState);
break;
}
*frame = _animationFrame;
return true;
}
bool AIScriptTyrellGuard::ChangeAnimationMode(int mode) {
switch (mode) {
case kAnimationModeIdle:
switch (_animationState) {
case 0:
_animationState = 8;
_animationFrame = 0;
break;
case 1:
_animationState = 2;
break;
case 3:
// fall through
case 4:
// fall through
case 5:
// fall through
case 6:
// fall through
case 7:
_resumeIdleAfterFramesetCompletesFlag = true;
break;
case 8:
break;
default:
_animationState = 0;
_animationFrame = 0;
break;
}
break;
case kAnimationModeTalk:
if (_animationState == 1) {
_animationState = 2;
} else if ((_animationState - 1 != 7 && _animationState - 1 != 10) || _animationState - 1 > 10) {
_animationState = 3;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
}
break;
case 12:
if (_animationState == 1) {
_animationState = 2;
} else if ((_animationState - 1 != 7 && _animationState - 1 != 10) || _animationState - 1 > 10) {
_animationState = 4;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
}
break;
case 13:
if (_animationState == 1) {
_animationState = 2;
} else if ((_animationState - 1 != 7 && _animationState - 1 != 10) || _animationState - 1 > 10) {
_animationState = 5;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
}
break;
case 14:
if (_animationState == 1) {
_animationState = 2;
} else if ((_animationState - 1 != 7 && _animationState - 1 != 10) || _animationState - 1 > 10) {
_animationState = 6;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
}
break;
case 15:
if (_animationState == 1) {
_animationState = 2;
} else if ((_animationState - 1 != 7 && _animationState - 1 != 10) || _animationState - 1 > 10) {
_animationState = 7;
_animationFrame = 0;
_resumeIdleAfterFramesetCompletesFlag = false;
}
break;
case 23:
_animationState = 8;
_animationFrame = 0;
break;
case 50:
_animationState = 11;
_animationFrame = 0;
break;
case 43:
// fall through
case 55:
if (_animationState != 1) {
_animationState = 1;
_animationFrame = 0;
}
break;
default:
debugC(6, kDebugAnimation, "AIScriptTyrellGuard::ChangeAnimationMode(%d) - Target mode is not supported", mode);
break;
}
return true;
}
void AIScriptTyrellGuard::QueryAnimationState(int *animationState, int *animationFrame, int *animationStateNext, int *animationNext) {
*animationState = _animationState;
*animationFrame = _animationFrame;
*animationStateNext = _animationStateNext;
*animationNext = _animationNext;
}
void AIScriptTyrellGuard::SetAnimationState(int animationState, int animationFrame, int animationStateNext, int animationNext) {
_animationState = animationState;
_animationFrame = animationFrame;
_animationStateNext = animationStateNext;
_animationNext = animationNext;
}
bool AIScriptTyrellGuard::ReachedMovementTrackWaypoint(int waypointId) {
return true;
}
void AIScriptTyrellGuard::FledCombat() {
// return false;
}
} // End of namespace BladeRunner

File diff suppressed because it is too large Load Diff