2019-10-18 22:23:40 +00:00
|
|
|
#include "common.h"
|
2020-04-17 13:31:11 +00:00
|
|
|
|
2019-10-18 22:23:40 +00:00
|
|
|
#include "SceneEdit.h"
|
|
|
|
|
2020-04-13 18:50:56 +00:00
|
|
|
#include "Automobile.h"
|
2020-04-12 09:06:33 +00:00
|
|
|
#include "Camera.h"
|
2020-04-13 18:50:56 +00:00
|
|
|
#include "CarCtrl.h"
|
|
|
|
#include "CivilianPed.h"
|
2020-04-12 09:06:33 +00:00
|
|
|
#include "FileMgr.h"
|
|
|
|
#include "Font.h"
|
|
|
|
#include "ModelIndices.h"
|
|
|
|
#include "ModelInfo.h"
|
2020-04-13 18:50:56 +00:00
|
|
|
#include "Pad.h"
|
2020-04-12 09:06:33 +00:00
|
|
|
#include "Ped.h"
|
|
|
|
#include "Population.h"
|
|
|
|
#include "Text.h"
|
2020-04-13 18:50:56 +00:00
|
|
|
#include "Timecycle.h"
|
|
|
|
#include "Streaming.h"
|
2020-04-12 09:06:33 +00:00
|
|
|
#include "Vehicle.h"
|
2020-04-13 18:50:56 +00:00
|
|
|
#include "WeaponInfo.h"
|
2020-04-12 09:06:33 +00:00
|
|
|
#include "World.h"
|
|
|
|
|
|
|
|
bool CSceneEdit::m_bEditOn;
|
|
|
|
int32 CSceneEdit::m_bCameraFollowActor;
|
|
|
|
bool CSceneEdit::m_bRecording;
|
|
|
|
CVector CSceneEdit::m_vecCurrentPosition;
|
|
|
|
CVector CSceneEdit::m_vecCamHeading;
|
|
|
|
CVector CSceneEdit::m_vecGotoPosition;
|
|
|
|
int32 CSceneEdit::m_nVehicle;
|
|
|
|
int32 CSceneEdit::m_nVehicle2;
|
|
|
|
int32 CSceneEdit::m_nActor;
|
|
|
|
int32 CSceneEdit::m_nActor2;
|
|
|
|
int32 CSceneEdit::m_nVehiclemodelId;
|
|
|
|
int32 CSceneEdit::m_nPedmodelId;
|
|
|
|
int16 CSceneEdit::m_nCurrentMovieCommand;
|
|
|
|
int16 CSceneEdit::m_nNumActors;
|
|
|
|
int16 CSceneEdit::m_nNumMovieCommands;
|
|
|
|
int16 CSceneEdit::m_nCurrentCommand;
|
|
|
|
int16 CSceneEdit::m_nCurrentVehicle;
|
2020-04-13 18:50:56 +00:00
|
|
|
int16 CSceneEdit::m_nCurrentActor;
|
|
|
|
int16 CSceneEdit::m_nWeaponType;
|
2020-04-12 09:06:33 +00:00
|
|
|
bool CSceneEdit::m_bCommandActive;
|
2020-04-13 18:50:56 +00:00
|
|
|
bool CSceneEdit::m_bActorSelected;
|
|
|
|
bool CSceneEdit::m_bActor2Selected;
|
|
|
|
bool CSceneEdit::m_bVehicleSelected;
|
2020-04-12 09:06:33 +00:00
|
|
|
int16 CSceneEdit::m_nNumVehicles;
|
|
|
|
CPed* CSceneEdit::pActors[NUM_ACTORS_IN_MOVIE];
|
|
|
|
CVehicle* CSceneEdit::pVehicles[NUM_VEHICLES_IN_MOVIE];
|
|
|
|
bool CSceneEdit::m_bDrawGotoArrow;
|
|
|
|
CMovieCommand CSceneEdit::Movie[NUM_COMMANDS_IN_MOVIE];
|
|
|
|
|
|
|
|
#define SHADOW_OFFSET (2.0f)
|
|
|
|
#define ACTION_MESSAGE_X_RIGHT (60.0f)
|
|
|
|
#define ACTION_MESSAGE_Y (8.0f)
|
|
|
|
#define SELECTED_MESSAGE_X_RIGHT (60.0f)
|
|
|
|
#define SELECTED_MESSAGE_Y (248.0f)
|
|
|
|
#define COMMAND_NAME_X_RIGHT (60.0f)
|
|
|
|
#define COMMAND_NAME_Y (38.0f)
|
|
|
|
#define COMMAND_NAME_HEIGHT (16.0f)
|
|
|
|
|
|
|
|
#define NUM_COMMANDS_TO_DRAW (9)
|
|
|
|
|
|
|
|
static const char* pCommandStrings[] = {
|
|
|
|
"do-nothing", "New Actor", "Move Actor", "Select Actor", "Delete Actor",
|
|
|
|
"New Vehicle", "Move Vehicle", "Select Vehicle", "Delete Vehicle", "Give Weapon",
|
|
|
|
"Goto", "Goto (wait)", "Get In Car", "Get Out Car", "Kill",
|
|
|
|
"Flee", "Wait", "Position Camera", "Set Camera Target", "Select Camera Mode",
|
|
|
|
"Save Movie", "Load Movie", "Play Movie", "END"
|
|
|
|
};
|
|
|
|
|
2020-05-10 15:49:33 +00:00
|
|
|
#ifdef CHECK_STRUCT_SIZES
|
2020-04-12 09:06:33 +00:00
|
|
|
static_assert(ARRAY_SIZE(pCommandStrings) == CSceneEdit::MOVIE_TOTAL_COMMANDS, "Scene edit: not all commands have names");
|
2020-05-10 15:49:33 +00:00
|
|
|
#endif
|
2020-04-12 09:06:33 +00:00
|
|
|
|
|
|
|
static int32 NextValidModelId(int32 mi, int32 step)
|
|
|
|
{
|
|
|
|
int32 result = -1;
|
|
|
|
int32 i = mi;
|
|
|
|
while (result == -1) {
|
2020-04-13 18:50:56 +00:00
|
|
|
i += step;
|
2020-05-10 15:09:57 +00:00
|
|
|
if (i < 0 || i > MODELINFOSIZE) {
|
2020-04-13 18:50:56 +00:00
|
|
|
step = -step;
|
2020-04-12 09:06:33 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
CBaseModelInfo* pInfo = CModelInfo::GetModelInfo(i);
|
|
|
|
CVehicleModelInfo* pVehicleInfo = (CVehicleModelInfo*)pInfo;
|
2020-04-13 18:50:56 +00:00
|
|
|
if (!pInfo)
|
2020-04-12 09:06:33 +00:00
|
|
|
continue;
|
2020-05-05 12:06:55 +00:00
|
|
|
if (pInfo->GetModelType() == MITYPE_PED
|
2020-04-13 18:50:56 +00:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
&& !(i >= MI_SPECIAL01 && i <= MI_SPECIAL04)
|
|
|
|
#endif
|
2020-05-05 12:06:55 +00:00
|
|
|
|| pInfo->GetModelType() == MITYPE_VEHICLE &&
|
2020-04-12 09:06:33 +00:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
(pVehicleInfo->m_vehicleType == VEHICLE_TYPE_CAR || pVehicleInfo->m_vehicleType == VEHICLE_TYPE_BOAT))
|
2020-04-13 18:50:56 +00:00
|
|
|
#else // && and || priority failure it seems, also crashes on special models
|
2020-04-12 09:06:33 +00:00
|
|
|
pVehicleInfo->m_vehicleType == VEHICLE_TYPE_CAR || pVehicleInfo->m_vehicleType == VEHICLE_TYPE_BOAT)
|
|
|
|
#endif
|
|
|
|
result = i;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::LoadMovie(void)
|
|
|
|
{
|
|
|
|
ReInitialise();
|
|
|
|
CFileMgr::SetDir("DATA");
|
|
|
|
int fid = CFileMgr::OpenFile("movie.dat", "r");
|
|
|
|
#ifdef FIX_BUGS
|
2020-04-14 17:16:02 +00:00
|
|
|
if (fid >= 0)
|
2020-04-12 09:06:33 +00:00
|
|
|
#endif
|
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
CFileMgr::Read(fid, (char*)&Movie, sizeof(Movie));
|
|
|
|
CFileMgr::Read(fid, (char*)&m_nNumMovieCommands, sizeof(m_nNumMovieCommands));
|
2020-04-12 09:06:33 +00:00
|
|
|
CFileMgr::CloseFile(fid);
|
|
|
|
}
|
|
|
|
CFileMgr::SetDir("");
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::SaveMovie(void)
|
|
|
|
{
|
|
|
|
CFileMgr::SetDir("DATA");
|
|
|
|
int fid = CFileMgr::OpenFileForWriting("movie.dat");
|
|
|
|
if (fid >= 0) {
|
2020-04-13 18:50:56 +00:00
|
|
|
CFileMgr::Write(fid, (char*)&Movie, sizeof(Movie));
|
|
|
|
CFileMgr::Write(fid, (char*)&m_nNumMovieCommands, sizeof(m_nNumMovieCommands));
|
2020-04-12 09:06:33 +00:00
|
|
|
CFileMgr::CloseFile(fid);
|
|
|
|
}
|
|
|
|
CFileMgr::SetDir("");
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::Initialise(void)
|
|
|
|
{
|
|
|
|
m_nActor = -1;
|
|
|
|
m_nActor2 = -1;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_nVehicle2 = -1;
|
|
|
|
m_nCurrentCommand = MOVIE_NEW_ACTOR;
|
|
|
|
m_nVehiclemodelId = MI_INFERNUS;
|
|
|
|
m_nPedmodelId = MI_MALE01;
|
|
|
|
m_nNumVehicles = 0;
|
|
|
|
m_nNumActors = 0;
|
|
|
|
m_nNumMovieCommands = 0;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
m_bRecording = true;
|
|
|
|
m_bEditOn = false;
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++)
|
|
|
|
pActors[i] = nil;
|
|
|
|
for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++)
|
|
|
|
pVehicles[i] = nil;
|
|
|
|
m_vecCamHeading = TheCamera.Cams[TheCamera.ActiveCam].Front;
|
|
|
|
m_vecGotoPosition = CVector(0.0f, 0.0f, 0.0f);
|
|
|
|
m_bCameraFollowActor = false;
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
|
|
|
|
m_bDrawGotoArrow = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::InitPlayback(void)
|
|
|
|
{
|
|
|
|
m_nVehiclemodelId = MI_INFERNUS;
|
|
|
|
m_nPedmodelId = MI_MALE01;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
m_nNumActors = 0;
|
|
|
|
m_nNumVehicles = 0;
|
|
|
|
m_nActor = -1;
|
|
|
|
m_nActor2 = -1;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_nVehicle2 = -1;
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true;
|
|
|
|
m_vecCamHeading = TheCamera.Cams[TheCamera.ActiveCam].Front;
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
|
|
|
|
if (pActors[i]) {
|
|
|
|
CPopulation::RemovePed(pActors[i]);
|
|
|
|
pActors[i] = nil;
|
|
|
|
}
|
|
|
|
}
|
2020-04-13 18:50:56 +00:00
|
|
|
m_nCurrentActor = 0;
|
2020-04-12 09:06:33 +00:00
|
|
|
for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
|
|
|
|
if (pVehicles[i]) {
|
|
|
|
CWorld::Remove(pVehicles[i]);
|
|
|
|
delete pVehicles[i];
|
|
|
|
pVehicles[i] = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_nCurrentVehicle = 0;
|
2020-04-13 18:50:56 +00:00
|
|
|
m_vecGotoPosition = CVector(0.0f, 0.0f, 0.0f);
|
2020-04-12 09:06:33 +00:00
|
|
|
m_nCurrentMovieCommand = MOVIE_DO_NOTHING;
|
|
|
|
m_bDrawGotoArrow = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::ReInitialise(void)
|
|
|
|
{
|
|
|
|
m_nVehiclemodelId = MI_INFERNUS;
|
|
|
|
m_nPedmodelId = MI_MALE01;
|
|
|
|
m_nCurrentCommand = MOVIE_NEW_ACTOR;
|
|
|
|
m_bEditOn = true;
|
|
|
|
m_bRecording = true;
|
|
|
|
m_bCommandActive = false;
|
2020-04-14 17:09:42 +00:00
|
|
|
#ifdef FIX_BUGS
|
|
|
|
m_bCameraFollowActor = false;
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].ResetStatics = true; // not enough...
|
|
|
|
#endif
|
2020-04-12 09:06:33 +00:00
|
|
|
m_nActor = -1;
|
|
|
|
m_nActor2 = -1;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_nVehicle2 = -1;
|
|
|
|
m_nNumMovieCommands = 0;
|
|
|
|
m_nCurrentMovieCommand = MOVIE_DO_NOTHING;
|
|
|
|
m_nNumActors = 0;
|
|
|
|
m_nNumVehicles = 0;
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
|
|
|
|
if (pActors[i]) {
|
|
|
|
CPopulation::RemovePed(pActors[i]);
|
|
|
|
pActors[i] = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
|
|
|
|
if (pVehicles[i]) {
|
|
|
|
CWorld::Remove(pVehicles[i]);
|
|
|
|
delete pVehicles[i];
|
|
|
|
pVehicles[i] = nil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < NUM_COMMANDS_IN_MOVIE; i++) {
|
|
|
|
Movie[i].m_nCommandId = MOVIE_DO_NOTHING;
|
|
|
|
Movie[i].m_vecPosition = CVector(0.0f, 0.0f, 0.0f);
|
|
|
|
Movie[i].m_vecCamera = CVector(0.0f, 0.0f, 0.0f);
|
|
|
|
Movie[i].m_nActorId = -1;
|
|
|
|
Movie[i].m_nActor2Id = -1;
|
|
|
|
Movie[i].m_nVehicleId = -1;
|
|
|
|
Movie[i].m_nModelIndex = 0;
|
|
|
|
}
|
|
|
|
m_vecGotoPosition = CVector(0.0f, 0.0f, 0.0f);
|
|
|
|
m_bDrawGotoArrow = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::Update(void)
|
|
|
|
{
|
|
|
|
if (!m_bEditOn)
|
|
|
|
return;
|
|
|
|
if (m_bRecording)
|
|
|
|
ProcessCommand();
|
|
|
|
else {
|
|
|
|
if (m_bCameraFollowActor && m_nActor != -1) {
|
|
|
|
if (pActors[m_nActor]->bInVehicle)
|
|
|
|
TheCamera.TakeControl(pActors[m_nActor]->m_pMyVehicle, CCam::MODE_BEHINDCAR, JUMP_CUT, CAMCONTROL_SCRIPT);
|
|
|
|
else
|
|
|
|
TheCamera.TakeControl(pActors[m_nActor], CCam::MODE_FOLLOWPED, JUMP_CUT, CAMCONTROL_SCRIPT);
|
|
|
|
}
|
|
|
|
PlayBack();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::Draw(void)
|
|
|
|
{
|
|
|
|
char str[200];
|
|
|
|
wchar wstr[200];
|
|
|
|
if (TheCamera.m_WideScreenOn)
|
|
|
|
return;
|
2020-04-13 18:50:56 +00:00
|
|
|
#ifndef FIX_BUGS
|
2020-04-12 09:06:33 +00:00
|
|
|
CFont::SetPropOff();
|
2020-04-13 18:50:56 +00:00
|
|
|
#endif
|
2020-04-12 09:06:33 +00:00
|
|
|
CFont::SetBackgroundOff();
|
|
|
|
CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
|
|
|
|
CFont::SetCentreOn();
|
|
|
|
CFont::SetRightJustifyOn();
|
|
|
|
CFont::SetRightJustifyWrap(0.0f);
|
|
|
|
CFont::SetBackGroundOnlyTextOff();
|
2020-04-13 18:50:56 +00:00
|
|
|
#ifdef FIX_BUGS
|
2020-06-07 02:03:06 +00:00
|
|
|
CFont::SetFontStyle(FONT_BANK);
|
2020-04-13 18:50:56 +00:00
|
|
|
CFont::SetPropOn();
|
|
|
|
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
|
|
|
|
CFont::SetDropShadowPosition(1);
|
|
|
|
#else
|
2020-04-12 09:06:33 +00:00
|
|
|
CFont::SetFontStyle(FONT_HEADING);
|
|
|
|
CFont::SetPropOff();
|
2020-04-13 18:50:56 +00:00
|
|
|
#endif
|
2020-04-12 09:06:33 +00:00
|
|
|
sprintf(str, "Action");
|
|
|
|
AsciiToUnicode(str, wstr);
|
|
|
|
CFont::SetColor(CRGBA(0, 0, 0, 0));
|
2020-04-13 18:50:56 +00:00
|
|
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(ACTION_MESSAGE_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(ACTION_MESSAGE_Y + SHADOW_OFFSET), wstr);
|
2020-04-12 09:06:33 +00:00
|
|
|
CFont::SetColor(CRGBA(193, 164, 120, 255));
|
|
|
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(ACTION_MESSAGE_X_RIGHT), SCREEN_SCALE_Y(ACTION_MESSAGE_Y), wstr);
|
|
|
|
sprintf(str, "Selected");
|
|
|
|
AsciiToUnicode(str, wstr);
|
|
|
|
CFont::SetColor(CRGBA(0, 0, 0, 0));
|
2020-04-13 18:50:56 +00:00
|
|
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(SELECTED_MESSAGE_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(SELECTED_MESSAGE_Y + SHADOW_OFFSET), wstr);
|
2020-04-12 09:06:33 +00:00
|
|
|
CFont::SetColor(CRGBA(193, 164, 120, 255));
|
|
|
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(SELECTED_MESSAGE_X_RIGHT), SCREEN_SCALE_Y(SELECTED_MESSAGE_Y), wstr);
|
|
|
|
CFont::SetCentreOff();
|
|
|
|
CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.7f));
|
2020-04-13 18:50:56 +00:00
|
|
|
#ifdef FIX_BUGS
|
2020-06-07 02:03:06 +00:00
|
|
|
CFont::SetFontStyle(FONT_BANK);
|
2020-04-13 18:50:56 +00:00
|
|
|
#else
|
2020-04-12 09:06:33 +00:00
|
|
|
CFont::SetFontStyle(FONT_HEADING);
|
2020-04-13 18:50:56 +00:00
|
|
|
#endif
|
2020-04-12 09:06:33 +00:00
|
|
|
CFont::SetColor(CRGBA(0, 0, 0, 0));
|
|
|
|
for (int i = 0; i < NUM_COMMANDS_TO_DRAW; i++) {
|
|
|
|
int16 nCommandDrawn = m_nCurrentCommand + i - NUM_COMMANDS_TO_DRAW / 2;
|
|
|
|
if (nCommandDrawn >= MOVIE_TOTAL_COMMANDS)
|
|
|
|
nCommandDrawn -= (MOVIE_TOTAL_COMMANDS - 1);
|
|
|
|
if (nCommandDrawn <= MOVIE_DO_NOTHING)
|
|
|
|
nCommandDrawn += (MOVIE_TOTAL_COMMANDS - 1);
|
2020-05-11 23:24:57 +00:00
|
|
|
sprintf(str, "%s", pCommandStrings[nCommandDrawn]);
|
2020-04-12 09:06:33 +00:00
|
|
|
AsciiToUnicode(str, wstr);
|
|
|
|
CFont::SetColor(CRGBA(0, 0, 0, 0));
|
2020-04-13 18:50:56 +00:00
|
|
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(COMMAND_NAME_X_RIGHT - SHADOW_OFFSET), SCREEN_SCALE_Y(COMMAND_NAME_Y + SHADOW_OFFSET + i * COMMAND_NAME_HEIGHT), wstr);
|
2020-04-12 09:06:33 +00:00
|
|
|
if (nCommandDrawn == m_nCurrentCommand)
|
|
|
|
CFont::SetColor(CRGBA(156, 91, 40, 255));
|
|
|
|
else
|
|
|
|
CFont::SetColor(CRGBA(193, 164, 120, 255));
|
|
|
|
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(COMMAND_NAME_X_RIGHT), SCREEN_SCALE_Y(COMMAND_NAME_Y + i * COMMAND_NAME_HEIGHT), wstr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::ProcessCommand(void)
|
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
if (!m_bCommandActive) {
|
|
|
|
ClearForNewCommand();
|
|
|
|
if (CPad::GetPad(1)->GetDPadUpJustDown()) {
|
|
|
|
if (--m_nCurrentCommand == MOVIE_DO_NOTHING)
|
|
|
|
m_nCurrentCommand = MOVIE_END;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetDPadDownJustDown()) {
|
|
|
|
if (++m_nCurrentCommand == MOVIE_TOTAL_COMMANDS)
|
|
|
|
m_nCurrentCommand = MOVIE_NEW_ACTOR;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
if (m_nCurrentCommand != MOVIE_DO_NOTHING)
|
|
|
|
m_bCommandActive = true;
|
|
|
|
}
|
2020-04-12 09:06:33 +00:00
|
|
|
return;
|
2020-04-13 18:50:56 +00:00
|
|
|
}
|
2020-04-12 09:06:33 +00:00
|
|
|
switch (m_nCurrentCommand) {
|
|
|
|
case MOVIE_DO_NOTHING:
|
|
|
|
m_bCommandActive = false;
|
|
|
|
break;
|
2020-04-13 18:50:56 +00:00
|
|
|
case MOVIE_NEW_ACTOR:
|
|
|
|
if (m_nActor == -1) {
|
|
|
|
if (m_nNumActors == NUM_ACTORS_IN_MOVIE)
|
|
|
|
break;
|
|
|
|
if (!CStreaming::HasModelLoaded(m_nPedmodelId)) {
|
|
|
|
CStreaming::RequestModel(m_nPedmodelId, 0);
|
|
|
|
#ifdef FIX_BUGS
|
|
|
|
CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CPed* pPed = new CCivilianPed(PEDTYPE_SPECIAL, m_nPedmodelId);
|
|
|
|
pPed->CharCreatedBy = MISSION_CHAR;
|
2020-04-30 10:48:01 +00:00
|
|
|
pPed->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
pPed->SetOrientation(0.0f, 0.0f, 0.0f);
|
|
|
|
CWorld::Add(pPed);
|
|
|
|
pPed->bUsesCollision = false;
|
|
|
|
pPed->bAffectedByGravity = false;
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
|
|
|
|
if (pActors[i] == nil) {
|
|
|
|
m_nActor = i;
|
|
|
|
pActors[i] = pPed;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2020-04-30 10:48:01 +00:00
|
|
|
pActors[m_nActor]->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
pActors[m_nActor]->SetOrientation(0.0f, 0.0f, 0.0f);
|
|
|
|
int32 mi = m_nPedmodelId;
|
|
|
|
if (CPad::GetPad(1)->GetLeftShoulder1JustDown())
|
|
|
|
mi = NextValidModelId(m_nPedmodelId, -1);
|
|
|
|
else if (CPad::GetPad(1)->GetRightShoulder1JustDown())
|
|
|
|
mi = NextValidModelId(m_nPedmodelId, 1);
|
|
|
|
if (mi == m_nPedmodelId) {
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
pActors[m_nActor]->bUsesCollision = true;
|
|
|
|
pActors[m_nActor]->bAffectedByGravity = true;
|
|
|
|
++m_nNumActors;
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_NEW_ACTOR;
|
|
|
|
Movie[m_nNumMovieCommands].m_vecPosition = m_vecCurrentPosition;
|
|
|
|
Movie[m_nNumMovieCommands].m_nModelIndex = m_nPedmodelId;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
CWorld::Remove(pActors[m_nActor]);
|
|
|
|
delete pActors[m_nActor];
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_nPedmodelId = mi;
|
|
|
|
if (pActors[m_nActor]) {
|
|
|
|
CWorld::Remove(pActors[m_nActor]);
|
|
|
|
delete pActors[m_nActor];
|
|
|
|
}
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_MOVE_ACTOR:
|
|
|
|
SelectActor();
|
|
|
|
if (m_bCommandActive)
|
|
|
|
break;
|
2020-04-30 10:48:01 +00:00
|
|
|
pActors[m_nActor]->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
m_bCommandActive = false;
|
|
|
|
#ifndef FIX_BUGS // why? it crashes, also makes no sense
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
#endif
|
|
|
|
SelectActor();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_SELECT_ACTOR:
|
|
|
|
SelectActor();
|
|
|
|
break;
|
|
|
|
case MOVIE_DELETE_ACTOR:
|
|
|
|
SelectActor();
|
|
|
|
if (m_bActorSelected) {
|
|
|
|
CPopulation::RemovePed(pActors[m_nActor]);
|
|
|
|
m_nCurrentActor = 0;
|
|
|
|
--m_nNumActors;
|
|
|
|
#ifdef FIX_BUGS
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
#else
|
|
|
|
m_nActor = -1;
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
#endif
|
|
|
|
SelectActor();
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_NEW_VEHICLE:
|
|
|
|
if (m_nVehicle == -1) {
|
|
|
|
if (m_nNumVehicles == NUM_VEHICLES_IN_MOVIE)
|
|
|
|
break;
|
|
|
|
if (!CStreaming::HasModelLoaded(m_nVehiclemodelId)) {
|
|
|
|
CStreaming::RequestModel(m_nVehiclemodelId, 0);
|
|
|
|
#ifdef FIX_BUGS
|
|
|
|
CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CVehicle* pVehicle = new CAutomobile(m_nVehiclemodelId, MISSION_VEHICLE);
|
2020-04-30 13:45:45 +00:00
|
|
|
pVehicle->SetStatus(STATUS_PHYSICS);
|
2020-04-30 10:48:01 +00:00
|
|
|
pVehicle->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
pVehicle->SetOrientation(0.0f, 0.0f, 0.0f);
|
|
|
|
CWorld::Add(pVehicle);
|
|
|
|
pVehicle->bUsesCollision = false;
|
|
|
|
pVehicle->bAffectedByGravity = false;
|
|
|
|
for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
|
|
|
|
if (pVehicles[i] == nil) {
|
|
|
|
m_nVehicle = i;
|
|
|
|
pVehicles[i] = pVehicle;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2020-04-30 10:48:01 +00:00
|
|
|
pVehicles[m_nVehicle]->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
pVehicles[m_nVehicle]->SetOrientation(0.0f, 0.0f, 0.0f);
|
|
|
|
int32 mi = m_nVehiclemodelId;
|
|
|
|
if (CPad::GetPad(1)->GetLeftShoulder1JustDown())
|
|
|
|
mi = NextValidModelId(m_nVehiclemodelId, -1);
|
|
|
|
else if (CPad::GetPad(1)->GetRightShoulder1JustDown())
|
|
|
|
mi = NextValidModelId(m_nVehiclemodelId, 1);
|
|
|
|
if (mi == m_nVehiclemodelId) {
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
pVehicles[m_nVehicle]->bUsesCollision = true;
|
|
|
|
pVehicles[m_nVehicle]->bAffectedByGravity = true;
|
|
|
|
++m_nNumVehicles;
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_NEW_VEHICLE;
|
|
|
|
Movie[m_nNumMovieCommands].m_vecPosition = m_vecCurrentPosition;
|
|
|
|
Movie[m_nNumMovieCommands].m_nModelIndex = m_nVehiclemodelId;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nVehicleId = m_nVehicle;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
CWorld::Remove(pVehicles[m_nVehicle]);
|
|
|
|
delete pVehicles[m_nVehicle];
|
|
|
|
pVehicles[m_nVehicle] = nil;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_nVehiclemodelId = mi;
|
|
|
|
if (pVehicles[m_nVehicle]) {
|
|
|
|
CWorld::Remove(pVehicles[m_nVehicle]);
|
|
|
|
delete pVehicles[m_nVehicle];
|
|
|
|
}
|
|
|
|
pVehicles[m_nVehicle] = nil;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_MOVE_VEHICLE:
|
|
|
|
SelectVehicle();
|
|
|
|
if (m_bCommandActive)
|
|
|
|
break;
|
2020-04-30 10:48:01 +00:00
|
|
|
pVehicles[m_nVehicle]->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
m_bCommandActive = false;
|
|
|
|
#ifndef FIX_BUGS // again, why? works wrong
|
|
|
|
pVehicles[m_nVehicle] = nil;
|
|
|
|
#endif
|
|
|
|
m_nVehicle = -1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_SELECT_VEHICLE:
|
|
|
|
SelectVehicle();
|
|
|
|
break;
|
|
|
|
case MOVIE_DELETE_VEHICLE:
|
|
|
|
SelectVehicle();
|
|
|
|
if (m_bVehicleSelected) {
|
|
|
|
CWorld::Remove(pVehicles[m_nVehicle]);
|
|
|
|
delete pVehicles[m_nVehicle];
|
|
|
|
m_nCurrentVehicle = 0;
|
|
|
|
--m_nNumVehicles;
|
|
|
|
pVehicles[m_nVehicle] = nil;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
SelectVehicle();
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pVehicles[m_nVehicle] = nil;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_GIVE_WEAPON:
|
|
|
|
if (m_bActorSelected) {
|
|
|
|
if (SelectWeapon()) {
|
|
|
|
m_bCommandActive = false;
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GIVE_WEAPON;
|
|
|
|
Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nModelIndex = m_nWeaponType;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
SelectActor();
|
|
|
|
m_bCommandActive = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_GOTO:
|
|
|
|
case MOVIE_GOTO_WAIT:
|
|
|
|
if (!m_bActorSelected) {
|
|
|
|
m_bDrawGotoArrow = true;
|
|
|
|
SelectActor();
|
|
|
|
if (m_nActor == -1)
|
|
|
|
m_bCommandActive = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_vecGotoPosition = m_vecCurrentPosition;
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
if (pActors[m_nActor]->bInVehicle) {
|
|
|
|
if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pActors[m_nActor]->m_pMyVehicle, m_vecGotoPosition, false))
|
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
|
|
|
|
else
|
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
|
2020-04-30 13:45:45 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->SetStatus(STATUS_PHYSICS);
|
2020-04-13 18:50:56 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->bEngineOn = true;
|
2020-04-19 16:34:08 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed = Max(16, pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed);
|
2020-04-13 18:50:56 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
|
|
|
TheCamera.TakeControl(pActors[m_nActor]->m_pMyVehicle, CCam::MODE_BEHINDCAR, JUMP_CUT, CAMCONTROL_SCRIPT);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_vecGotoPosition);
|
|
|
|
TheCamera.TakeControl(pActors[m_nActor], CCam::MODE_FOLLOWPED, JUMP_CUT, CAMCONTROL_SCRIPT);
|
|
|
|
}
|
|
|
|
m_bDrawGotoArrow = false;
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GOTO;
|
|
|
|
Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
|
|
|
|
Movie[m_nNumMovieCommands++].m_vecPosition = m_vecGotoPosition;
|
|
|
|
}
|
|
|
|
if (!m_bDrawGotoArrow) {
|
|
|
|
if (pActors[m_nActor]->bInVehicle && pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission == MISSION_NONE ||
|
|
|
|
!pActors[m_nActor]->bInVehicle && pActors[m_nActor]->m_objective == OBJECTIVE_NONE) {
|
|
|
|
if (pActors[m_nActor]) // if there is something that requires this check the least, it's this one
|
|
|
|
m_vecCamHeading = TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity->GetPosition() - TheCamera.Cams[TheCamera.ActiveCam].Source;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Mode = CCam::MODE_FIGHT_CAM_RUNABOUT;
|
|
|
|
m_vecCurrentPosition = pActors[m_nActor]->GetPosition();
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_NONE);
|
|
|
|
if (pActors[m_nActor]->bInVehicle)
|
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_GET_IN_CAR:
|
|
|
|
if (m_bActorSelected)
|
|
|
|
SelectVehicle();
|
|
|
|
else {
|
|
|
|
SelectActor();
|
|
|
|
if (m_nActor != -1)
|
|
|
|
m_bCommandActive = true;
|
|
|
|
}
|
|
|
|
if (m_bVehicleSelected) {
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicles[m_nVehicle]);
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GET_IN_CAR;
|
|
|
|
Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nVehicleId = m_nVehicle;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pVehicles[m_nVehicle] = nil;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_GET_OUT_CAR:
|
|
|
|
SelectActor();
|
|
|
|
if (m_bActorSelected) {
|
|
|
|
if (pActors[m_nActor]->bInVehicle) {
|
2020-07-03 13:51:33 +00:00
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_LEAVE_CAR);
|
2020-04-13 18:50:56 +00:00
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_GET_OUT_CAR;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
|
|
|
|
}
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pVehicles[m_nVehicle] = nil;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_KILL:
|
|
|
|
if (!m_bActorSelected) {
|
|
|
|
SelectActor();
|
|
|
|
m_bCommandActive = true;
|
|
|
|
}
|
|
|
|
else if (!m_bActor2Selected) {
|
|
|
|
SelectActor2();
|
|
|
|
if (m_bActorSelected && m_bActor2Selected && m_nActor != -1 && m_nActor2 != -1 && m_nActor != m_nActor2) {
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pActors[m_nActor2]);
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_KILL;
|
|
|
|
Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nActor2Id = m_nActor2;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
pActors[m_nActor2] = nil;
|
|
|
|
m_nActor2 = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_FLEE:
|
|
|
|
if (!m_bActorSelected) {
|
|
|
|
SelectActor();
|
|
|
|
m_bCommandActive = true;
|
|
|
|
}
|
|
|
|
else if (!m_bActor2Selected) {
|
|
|
|
SelectActor2();
|
|
|
|
if (m_bActorSelected && m_bActor2Selected && m_nActor != -1 && m_nActor2 != -1 && m_nActor != m_nActor2) {
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pActors[m_nActor2]);
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_FLEE;
|
|
|
|
Movie[m_nNumMovieCommands].m_nActorId = m_nActor;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nActor2Id = m_nActor2;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
pActors[m_nActor2] = nil;
|
|
|
|
m_nActor2 = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_WAIT:
|
|
|
|
SelectActor();
|
|
|
|
if (m_bActorSelected) {
|
2020-07-03 13:51:33 +00:00
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_WAIT_ON_FOOT);
|
2020-04-14 17:09:42 +00:00
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_WAIT;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
|
2020-04-13 18:50:56 +00:00
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pActors[m_nActor] = nil;
|
|
|
|
m_nActor = -1;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_POSITION_CAMERA:
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_POSITION_CAMERA;
|
|
|
|
Movie[m_nNumMovieCommands].m_vecPosition = TheCamera.Cams[TheCamera.ActiveCam].Source;
|
|
|
|
Movie[m_nNumMovieCommands++].m_vecCamera = m_vecCamHeading;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_SET_CAMERA_TARGET:
|
|
|
|
if (!m_bActorSelected) {
|
|
|
|
SelectActor();
|
|
|
|
m_bCommandActive = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity = pActors[m_nActor];
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
Movie[m_nNumMovieCommands].m_nCommandId = MOVIE_SET_CAMERA_TARGET;
|
|
|
|
Movie[m_nNumMovieCommands++].m_nActorId = m_nActor;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_SELECT_CAMERA_MODE:
|
|
|
|
m_bCommandActive = false;
|
|
|
|
break;
|
|
|
|
case MOVIE_SAVE_MOVIE:
|
|
|
|
SaveMovie();
|
|
|
|
break;
|
|
|
|
case MOVIE_LOAD_MOVIE:
|
|
|
|
LoadMovie();
|
|
|
|
break;
|
|
|
|
case MOVIE_PLAY_MOVIE:
|
|
|
|
InitPlayback();
|
|
|
|
LoadMovie();
|
|
|
|
m_bRecording = false;
|
|
|
|
break;
|
|
|
|
case MOVIE_END:
|
|
|
|
m_bRecording = false;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert(0);
|
2020-04-12 09:06:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::PlayBack(void)
|
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
m_nCurrentCommand = Movie[m_nCurrentMovieCommand].m_nCommandId;
|
|
|
|
if (m_nCurrentMovieCommand >= m_nNumMovieCommands) {
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
m_nCurrentCommand = MOVIE_DO_NOTHING;
|
|
|
|
m_bRecording = true;
|
|
|
|
ReInitialise();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (m_nCurrentCommand) {
|
|
|
|
case MOVIE_DO_NOTHING:
|
|
|
|
case MOVIE_MOVE_ACTOR:
|
|
|
|
case MOVIE_SELECT_ACTOR:
|
|
|
|
case MOVIE_DELETE_ACTOR:
|
|
|
|
case MOVIE_MOVE_VEHICLE:
|
|
|
|
case MOVIE_SELECT_VEHICLE:
|
|
|
|
case MOVIE_DELETE_VEHICLE:
|
|
|
|
break;
|
|
|
|
case MOVIE_NEW_ACTOR:
|
|
|
|
{
|
|
|
|
m_nPedmodelId = Movie[m_nCurrentMovieCommand].m_nModelIndex;
|
|
|
|
m_vecCurrentPosition = Movie[m_nCurrentMovieCommand].m_vecPosition;
|
|
|
|
if (!CStreaming::HasModelLoaded(m_nPedmodelId)) {
|
|
|
|
CStreaming::RequestModel(m_nPedmodelId, 0);
|
|
|
|
#ifdef FIX_BUGS
|
|
|
|
CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CPed* pPed = new CCivilianPed(PEDTYPE_SPECIAL, m_nPedmodelId);
|
|
|
|
pPed->CharCreatedBy = MISSION_CHAR;
|
|
|
|
CWorld::Add(pPed);
|
2020-04-30 10:48:01 +00:00
|
|
|
pPed->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
pPed->SetOrientation(0.0f, 0.0f, 0.0f);
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
|
|
|
|
if (pActors[i] == nil) {
|
|
|
|
m_nActor = i;
|
|
|
|
pActors[i] = pPed;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_nNumActors++;
|
|
|
|
m_nCurrentMovieCommand++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MOVIE_NEW_VEHICLE:
|
|
|
|
{
|
|
|
|
m_nVehiclemodelId = Movie[m_nCurrentMovieCommand].m_nModelIndex;
|
|
|
|
m_vecCurrentPosition = Movie[m_nCurrentMovieCommand].m_vecPosition;
|
|
|
|
if (!CStreaming::HasModelLoaded(m_nVehiclemodelId)) {
|
|
|
|
CStreaming::RequestModel(m_nVehiclemodelId, 0);
|
|
|
|
#ifdef FIX_BUGS
|
|
|
|
CStreaming::LoadAllRequestedModels(false); // otherwise gets stuck :(
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
CVehicle* pVehicle = new CAutomobile(m_nVehiclemodelId, MISSION_VEHICLE);
|
2020-04-30 13:45:45 +00:00
|
|
|
pVehicle->SetStatus(STATUS_PHYSICS);
|
2020-04-30 10:48:01 +00:00
|
|
|
pVehicle->SetPosition(m_vecCurrentPosition);
|
2020-04-13 18:50:56 +00:00
|
|
|
pVehicle->SetOrientation(0.0f, 0.0f, 0.0f);
|
|
|
|
CWorld::Add(pVehicle);
|
|
|
|
for (int i = 0; i < NUM_VEHICLES_IN_MOVIE; i++) {
|
|
|
|
if (pVehicles[i] == nil) {
|
|
|
|
m_nVehicle = i;
|
|
|
|
pVehicles[i] = pVehicle;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_nNumVehicles++;
|
|
|
|
m_nCurrentMovieCommand++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MOVIE_GIVE_WEAPON:
|
|
|
|
m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
|
|
|
|
m_nWeaponType = Movie[m_nCurrentMovieCommand].m_nModelIndex;
|
|
|
|
pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
|
|
|
|
pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
|
|
|
|
pActors[m_nActor]->SetCurrentWeapon(m_nWeaponType);
|
|
|
|
m_nCurrentMovieCommand++;
|
|
|
|
break;
|
|
|
|
case MOVIE_GOTO:
|
|
|
|
case MOVIE_GOTO_WAIT:
|
|
|
|
m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
|
|
|
|
m_vecGotoPosition = Movie[m_nCurrentMovieCommand].m_vecPosition;
|
|
|
|
if (pActors[m_nActor]->bInVehicle) {
|
|
|
|
if (pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS &&
|
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission != MISSION_GOTOCOORDS_STRAIGHT) {
|
|
|
|
if ((pActors[m_nActor]->m_pMyVehicle->GetPosition() - m_vecGotoPosition).Magnitude() < 5.0f) {
|
|
|
|
if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pActors[m_nActor]->m_pMyVehicle, m_vecGotoPosition, false))
|
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
|
|
|
|
else
|
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS;
|
2020-04-30 13:45:45 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->SetStatus(STATUS_PHYSICS);
|
2020-04-13 18:50:56 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->bEngineOn = true;
|
2020-04-19 16:34:08 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed = Max(16, pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nCruiseSpeed);
|
2020-04-13 18:50:56 +00:00
|
|
|
pActors[m_nActor]->m_pMyVehicle->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
|
|
|
|
if (m_nCurrentCommand != MOVIE_GOTO_WAIT)
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (pActors[m_nActor]->m_objective != OBJECTIVE_GOTO_AREA_ON_FOOT) {
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, m_vecGotoPosition);
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case MOVIE_GET_IN_CAR:
|
|
|
|
m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
|
|
|
|
if (!pActors[m_nActor]->bInVehicle){
|
|
|
|
m_nVehicle = Movie[m_nCurrentMovieCommand].m_nVehicleId;
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicles[m_nVehicle]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
break;
|
|
|
|
case MOVIE_GET_OUT_CAR:
|
|
|
|
m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
|
|
|
|
if (pActors[m_nActor]->bInVehicle)
|
2020-07-03 13:51:33 +00:00
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_LEAVE_CAR);
|
2020-04-13 18:50:56 +00:00
|
|
|
else
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
break;
|
|
|
|
case MOVIE_KILL:
|
|
|
|
m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
|
|
|
|
m_nActor2 = Movie[m_nCurrentMovieCommand].m_nActor2Id;
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pActors[m_nActor2]);
|
|
|
|
if (pActors[m_nActor2]->GetPedState() == PED_DEAD)
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
break;
|
|
|
|
case MOVIE_FLEE:
|
|
|
|
m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
|
|
|
|
m_nActor2 = Movie[m_nCurrentMovieCommand].m_nActor2Id;
|
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pActors[m_nActor2]);
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
break;
|
|
|
|
case MOVIE_WAIT:
|
|
|
|
m_nActor = Movie[m_nCurrentMovieCommand].m_nActorId;
|
2020-07-03 13:51:33 +00:00
|
|
|
pActors[m_nActor]->SetObjective(OBJECTIVE_WAIT_ON_FOOT);
|
2020-04-13 18:50:56 +00:00
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
break;
|
|
|
|
case MOVIE_POSITION_CAMERA:
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = Movie[m_nCurrentMovieCommand].m_vecPosition;
|
|
|
|
m_vecCamHeading = Movie[m_nCurrentMovieCommand].m_vecCamera;
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Front = m_vecCamHeading;
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
break;
|
|
|
|
case MOVIE_SET_CAMERA_TARGET:
|
|
|
|
m_bCameraFollowActor = true;
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].CamTargetEntity = pActors[Movie[m_nNumMovieCommands].m_nActorId];
|
|
|
|
TheCamera.pTargetEntity = pActors[Movie[m_nNumMovieCommands].m_nActorId];
|
|
|
|
TheCamera.m_bLookingAtPlayer = false;
|
|
|
|
++m_nCurrentMovieCommand;
|
|
|
|
break;
|
|
|
|
case MOVIE_SELECT_CAMERA_MODE:
|
|
|
|
m_bCommandActive = false; // this is wrong
|
|
|
|
break;
|
|
|
|
}
|
2020-04-12 09:06:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::ClearForNewCommand(void)
|
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
m_nActor = -1;
|
|
|
|
m_nActor2 = -1;
|
|
|
|
m_nVehicle = -1;
|
|
|
|
m_bActorSelected = false;
|
|
|
|
m_bActor2Selected = false;
|
|
|
|
m_bVehicleSelected = false;
|
|
|
|
m_bDrawGotoArrow = false;
|
2020-04-12 09:06:33 +00:00
|
|
|
}
|
|
|
|
void CSceneEdit::SelectActor(void)
|
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
m_bActorSelected = false;
|
|
|
|
if (m_nActor != -1) {
|
|
|
|
if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
|
|
|
|
CPed* pPed;
|
|
|
|
do {
|
|
|
|
if (--m_nActor < 0)
|
|
|
|
m_nActor = NUM_ACTORS_IN_MOVIE - 1;
|
|
|
|
pPed = pActors[m_nActor];
|
|
|
|
} while (pPed == nil);
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetRightShoulder1JustDown()) {
|
|
|
|
CPed* pPed;
|
|
|
|
do {
|
|
|
|
if (++m_nActor == NUM_ACTORS_IN_MOVIE)
|
|
|
|
m_nActor = 0;
|
|
|
|
pPed = pActors[m_nActor];
|
|
|
|
} while (pPed == nil);
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
|
|
|
|
}
|
|
|
|
m_vecCurrentPosition = pActors[m_nActor]->GetPosition();
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
m_bActorSelected = true;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
m_nActor = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (m_nNumActors != 0) {
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
|
|
|
|
if (pActors[i] != nil) {
|
|
|
|
m_nActor = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = pActors[m_nActor]->GetPosition() - m_vecCamHeading;
|
|
|
|
if (m_nNumActors == 1) {
|
|
|
|
m_bActorSelected = true;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
2020-04-12 09:06:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::SelectActor2(void)
|
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
m_bActor2Selected = false;
|
|
|
|
if (m_nNumActors <= 1) {
|
|
|
|
m_bCommandActive = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (m_nActor2 != -1) {
|
|
|
|
if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
|
|
|
|
CPed* pPed;
|
|
|
|
do {
|
|
|
|
if (--m_nActor2 < 0)
|
|
|
|
m_nActor2 = NUM_ACTORS_IN_MOVIE - 1;
|
|
|
|
pPed = pActors[m_nActor2];
|
|
|
|
} while (pPed == nil || pPed == pActors[m_nActor]);
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetRightShoulder1JustDown()) {
|
|
|
|
CPed* pPed;
|
|
|
|
do {
|
|
|
|
if (++m_nActor2 == NUM_ACTORS_IN_MOVIE)
|
|
|
|
m_nActor2 = 0;
|
|
|
|
pPed = pActors[m_nActor2];
|
|
|
|
} while (pPed == nil || pPed == pActors[m_nActor]);
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = pPed->GetPosition() - m_vecCamHeading;
|
|
|
|
}
|
|
|
|
m_vecCurrentPosition = pActors[m_nActor2]->GetPosition();
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
m_bActor2Selected = true;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
m_nActor2 = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
|
|
|
|
if (pActors[i] != nil && pActors[m_nActor] != pActors[i] ) {
|
|
|
|
m_nActor2 = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = pActors[m_nActor2]->GetPosition() - m_vecCamHeading;
|
|
|
|
}
|
2020-04-12 09:06:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CSceneEdit::SelectVehicle(void)
|
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
m_bVehicleSelected = false;
|
|
|
|
if (m_nVehicle != -1) {
|
|
|
|
if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
|
|
|
|
CVehicle* pVehicle;
|
|
|
|
do {
|
|
|
|
if (--m_nVehicle < 0)
|
|
|
|
m_nVehicle = NUM_VEHICLES_IN_MOVIE - 1;
|
|
|
|
pVehicle = pVehicles[m_nVehicle];
|
|
|
|
} while (pVehicle == nil);
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetRightShoulder1JustDown()) {
|
|
|
|
CVehicle* pVehicle;
|
|
|
|
do {
|
|
|
|
if (++m_nVehicle == NUM_VEHICLES_IN_MOVIE)
|
|
|
|
m_nVehicle = 0;
|
|
|
|
pVehicle = pVehicles[m_nVehicle];
|
|
|
|
} while (pVehicle == nil);
|
|
|
|
}
|
|
|
|
m_vecCurrentPosition = pVehicles[m_nVehicle]->GetPosition();
|
|
|
|
TheCamera.Cams[TheCamera.ActiveCam].Source = pVehicles[m_nVehicle]->GetPosition() - m_vecCamHeading;
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
m_bVehicleSelected = true;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
m_nVehicle = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (m_nNumVehicles != 0) {
|
|
|
|
for (int i = 0; i < NUM_ACTORS_IN_MOVIE; i++) {
|
|
|
|
if (pVehicles[i] != nil) {
|
|
|
|
m_nVehicle = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-12 09:06:33 +00:00
|
|
|
}
|
|
|
|
|
2020-04-13 18:50:56 +00:00
|
|
|
bool CSceneEdit::SelectWeapon(void)
|
2020-04-12 09:06:33 +00:00
|
|
|
{
|
2020-04-13 18:50:56 +00:00
|
|
|
if (m_nWeaponType == WEAPONTYPE_UNARMED) {
|
|
|
|
m_nWeaponType = WEAPONTYPE_COLT45;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetLeftShoulder1JustDown()) {
|
|
|
|
if (++m_nWeaponType >= WEAPONTYPE_DETONATOR)
|
|
|
|
m_nWeaponType = WEAPONTYPE_BASEBALLBAT;
|
|
|
|
pActors[m_nActor]->ClearWeapons();
|
|
|
|
pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
|
|
|
|
pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
|
|
|
|
pActors[m_nActor]->SetCurrentWeapon(m_nWeaponType);
|
|
|
|
}
|
|
|
|
else if (CPad::GetPad(1)->GetRightShoulder1JustDown()){
|
|
|
|
if (--m_nWeaponType <= WEAPONTYPE_UNARMED)
|
|
|
|
m_nWeaponType = WEAPONTYPE_GRENADE;
|
|
|
|
pActors[m_nActor]->ClearWeapons();
|
|
|
|
pActors[m_nActor]->GiveWeapon((eWeaponType)m_nWeaponType, 1000);
|
|
|
|
pActors[m_nActor]->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pActors[m_nActor]->GetWeapon()->m_eWeaponType)->m_nModelId);
|
|
|
|
pActors[m_nActor]->SetCurrentWeapon(m_nWeaponType);
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetTriangleJustDown()) {
|
|
|
|
m_bCommandActive = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (CPad::GetPad(1)->GetCircleJustDown()) {
|
|
|
|
pActors[m_nActor]->ClearWeapons();
|
|
|
|
m_nWeaponType = WEAPONTYPE_UNARMED;
|
|
|
|
m_bCommandActive = false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return false;
|
2020-05-11 23:24:57 +00:00
|
|
|
}
|