Files
GTASource/game/control/GarageEditor.cpp
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

1256 lines
40 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// FILE : control/GarageEditor.cpp
// PURPOSE : debug tools to allow management and editing of garages
// AUTHOR : Flavius Alecu
// CREATED : 17/11/2011
//
/////////////////////////////////////////////////////////////////////////////////
#include "GarageEditor.h"
#include "Garages.h"
#include "garages_parser.h"
#include "objects/Door.h"
#include "grcore\debugdraw.h"
#include "grcore\setup.h"
AI_OPTIMISATIONS()
#if __BANK
#include "camera/CamInterface.h"
#include "grcore/debugdraw.h"
#include "fwscene/world/WorldLimits.h"
#include "peds/ped.h"
#include "script/script.h"
#include "game/ModelIndices.h"
bool CGarageEditor::ms_bDisplayAllGarages = false;
bool CGarageEditor::ms_bDisplayBoundingBoxes = false;
float CGarageEditor::ms_baseX = 0.f;
float CGarageEditor::ms_baseY = 0.f;
float CGarageEditor::ms_baseZ = 0.f;
float CGarageEditor::ms_delta1X = 0.f;
float CGarageEditor::ms_delta1Y = 0.f;
float CGarageEditor::ms_delta2X = 0.f;
float CGarageEditor::ms_delta2Y = 0.f;
float CGarageEditor::ms_ceilingZ = 0.f;
s32 CGarageEditor::ms_type = -1;
int CGarageEditor::ms_permittedVehicleType = 0;
bool CGarageEditor::ms_startWithVehicleSavingEnable = true;
bool CGarageEditor::ms_vehicleSavingEnable = true;
bool CGarageEditor::ms_useLineIntersection= false;
CUiGadgetSimpleListAndWindow* CGarageEditor::ms_pBoxListWindow = NULL;
bool CGarageEditor::ms_bDisplayGarageDebugInfo = false;
bool CGarageEditor::ms_bDisplayBoundingVolumePoints = false;
bool CGarageEditor::ms_drawClearObjectsSphere = false;
bool CGarageEditor::ms_drawCentreSphere = false;
int CGarageEditor::ms_selectedBox = 0;
char CGarageEditor::ms_achCurrentGarageName[GARAGE_NAME_MAX];
bool CGarageEditor::ms_debugTestPeds = true;
bool CGarageEditor::ms_debugTestVehicles = true;
bool CGarageEditor::ms_debugTestObjects = true;
int CGarageEditor::ms_OwnerSelection = 0;
u8 CGarageEditor::ms_SelectedBoxPulse = 0;
bool CGarageEditor::ms_bEnclosedGarageFlag = false;
bool CGarageEditor::ms_bMPGarageFlag = false;
bool CGarageEditor::ms_bExteriorFlag = false;
bool CGarageEditor::ms_bInteriorFlag = false;
bool CGarageEditor::ms_drawSmallSpheres = false;
bool CGarageEditor::ms_drawLargeSpheres = true;
bool CGarageEditor::ms_drawRectLines = true;
bool CGarageEditor::ms_drawBox2DTest = false;
namespace object_commands
{
bool CommandIsSavingEnableForGarage(int garageHash);
void CommandEnableSavingInGarage(int garageHash, bool enable);
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: InitWidgets
// PURPOSE: creates widgets for editing / displaying garages
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::InitWidgets(bkBank& bank)
{
bank.PushGroup("Garage Editor");
bank.AddToggle("Draw garages", &ms_bDisplayAllGarages, datCallback(UiGadgetsCB));
bank.AddToggle("Draw garage bboxes", &ms_bDisplayBoundingBoxes, datCallback(UiGadgetsCB));
bank.AddButton("Create garage at camera pos", datCallback(CreateGarageAtCameraPosCB));
bank.AddButton("Delete current garage", datCallback(DeleteCurrentGarageCB));
bank.AddSeparator();
bank.AddToggle("Draw garage Debug Info", &ms_bDisplayGarageDebugInfo);
bank.AddToggle("Draw player debug visualisations", &ms_bDisplayBoundingVolumePoints);
bank.AddToggle("Draw player Quad Test points", &ms_drawSmallSpheres);
bank.AddToggle("Draw player Box Test points", &ms_drawLargeSpheres);
bank.AddToggle("Draw player Intersection Quad", &ms_drawRectLines);
bank.AddToggle("Draw Active Box Intersection Quad", &ms_drawBox2DTest);
bank.AddToggle("Debug Info - Search Peds", &ms_debugTestPeds);
bank.AddToggle("Debug Info - Search Vehicle", &ms_debugTestVehicles);
bank.AddToggle("Debug Info - Search Objects", &ms_debugTestObjects);
bank.AddSeparator();
bank.AddToggle("Draw clear objects sphere", &ms_drawClearObjectsSphere);
bank.AddToggle("Draw centre of garage sphere", &ms_drawCentreSphere);
bank.AddSeparator();
bank.AddTitle("Tweak currently selected");
bank.AddText("Garage name", ms_achCurrentGarageName, 256, datCallback(SetNameCB));
const char *ownerNames[] = { "Any", "Michael", "Franklin", "Trevor" };
bank.AddCombo("Owner", &ms_OwnerSelection, NELEM(ownerNames), ownerNames, datCallback(SetOwnerCB), "The Garage Owner");
bank.AddText("Selected Box", &ms_selectedBox, datCallback(SelectedBoxCallback));
bank.AddButton("Create Box at camera pos", datCallback(CreateBoxAtCameraPosCB));
bank.AddButton("Delete current Box", datCallback(DeleteCurrentBoxCB));
bank.AddSlider("Base X", &ms_baseX, WORLDLIMITS_XMIN, WORLDLIMITS_XMAX, 0.1f, datCallback(ResetCurrentGarageBBCallback));
bank.AddSlider("Base Y", &ms_baseY, WORLDLIMITS_YMIN, WORLDLIMITS_YMAX, 0.1f, datCallback(ResetCurrentGarageBBCallback));
bank.AddSlider("Base Z", &ms_baseZ, WORLDLIMITS_ZMIN, WORLDLIMITS_ZMAX, 0.1f, datCallback(ResetCurrentGarageBBCallback));
bank.AddSlider("Delta 1 X", &ms_delta1X, -50.f, 50.f, 0.1f, datCallback(ResetCurrentGarageBBCallback));
bank.AddSlider("Delta 1 Y", &ms_delta1Y, -50.f, 50.f, 0.1f, datCallback(ResetCurrentGarageBBCallback));
bank.AddButton("Snap Delat2 to be perpendicular to Delta1", datCallback(SnapDelta2PerpendicularToDelta1CB));
bank.AddSlider("Delta 2 X", &ms_delta2X, -50.f, 50.f, 0.1f, datCallback(ResetCurrentGarageBBCallback));
bank.AddSlider("Delta 2 Y", &ms_delta2Y, -50.f, 50.f, 0.1f, datCallback(ResetCurrentGarageBBCallback));
bank.AddButton("Snap Delat1 to be perpendicular to Delta2", datCallback(SnapDelta1PerpendicularToDelta2CB));
bank.AddSlider("Ceiling Z", &ms_ceilingZ, WORLDLIMITS_ZMIN, WORLDLIMITS_ZMAX, 0.1f);
bank.AddToggle("Is Enclosed Garage", &ms_bEnclosedGarageFlag, datCallback(EnclosedGarageFlagSetCB));
bank.AddToggle("Is MP Garage", &ms_bMPGarageFlag, datCallback(MPGarageFlagSetCB));
bank.AddToggle("Is Exterior Box", &ms_bExteriorFlag, datCallback(ExteriorFlagSetCB));
bank.AddToggle("Is Interior Box", &ms_bInteriorFlag, datCallback(InteriorFlagSetCB));
const char* garageTypes[] = { "None", "Mission", "Respray", "Script", "Ambient parking", "Safe house" };
bank.AddCombo("Type", &ms_type, NELEM(garageTypes), &garageTypes[0]);
const char* vehicleTypes[] = { "Default", "Helicopters", "Boats"};
bank.AddCombo("Permitted Vehicle Type", &ms_permittedVehicleType, NELEM(vehicleTypes), &vehicleTypes[0]);
bank.AddToggle("Start with Vehicle Saving Enabled", &ms_startWithVehicleSavingEnable);
bank.AddToggle("Vehicle Saving Enabled", &ms_vehicleSavingEnable);
bank.AddToggle("Use line intersection for Partially inside test", &ms_useLineIntersection);
bank.AddButton("Clear selected garage", datCallback(ClearSelectedGarageCB));
bank.AddButton("Clear selected garage of Peds", datCallback(ClearSelectedGarageOfPedsCB));
bank.AddButton("Clear selected garage of Vehicles", datCallback(ClearSelectedGarageOfVehiclesCB));
bank.AddButton("Clear selected garage of objects", datCallback(ClearSelectedGarageOfObjectsCB));
bank.AddSeparator();
bank.AddTitle("Save or load common:/data/garages.meta");
bank.AddButton("Save garages", datCallback(Save));
bank.AddButton("Reload garages", datCallback(Load));
bank.PopGroup();
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: UpdateDebug
// PURPOSE: handles debug draw etc for editing / display cull boxes
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::UpdateDebug()
{
int garageIndex = ms_pBoxListWindow ? ms_pBoxListWindow->GetCurrentIndex() : -1;
if (ms_bDisplayAllGarages)
{
DisplayGarages();
if (garageIndex != -1)
{
if (ms_pBoxListWindow->UserProcessClick())
{
RefreshTweakVals();
}
else
{
if (garageIndex >=0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage& g = CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()];
CGarage::Box box;
box.BaseX = ms_baseX;
box.BaseY = ms_baseY;
box.BaseZ = ms_baseZ;
box.Delta1X = ms_delta1X;
box.Delta1Y = ms_delta1Y;
box.Delta2X = ms_delta2X;
box.Delta2Y = ms_delta2Y;
box.CeilingZ = ms_ceilingZ;
box.useLineIntersection = ms_useLineIntersection;
g.UpdateSize(ms_selectedBox, box);
g.SetType((GarageType)ms_type);
if (ms_permittedVehicleType == 1)
{
g.m_permittedVehicleType = VEHICLE_TYPE_HELI;
}
else if (ms_permittedVehicleType == 2)
{
g.m_permittedVehicleType = VEHICLE_TYPE_BOAT;
}
else
{
g.m_permittedVehicleType = VEHICLE_TYPE_NONE;
}
g.Flags.bSavingVehiclesWasEnabledBeforeSave = ms_startWithVehicleSavingEnable;
object_commands::CommandEnableSavingInGarage(g.name.GetHash(), ms_vehicleSavingEnable);
// g.Flags.bSavingVehiclesEnabled = ms_vehicleSavingEnable;
}
}
}
}
if (ms_bDisplayGarageDebugInfo && garageIndex >=0 && garageIndex < CGarages::aGarages.GetCount())
{
const float _XPos = 270.0f;
const float _YPos = 580.0f;
const float _YInc = 10.0f;
Vector2 startPosition(_XPos, _YPos);
if (CGarages::IsGarageEmpty(garageIndex))
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
const atVarString empty("Garage is Empty");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), empty, true, 1.0f, 1.0f);
startPosition.y += _YInc;
grcDebugDraw::TextFontPop();
}
const CPed *pPed = FindPlayerPed();
if (pPed->GetPedConfigFlag( CPED_CONFIG_FLAG_InVehicle ), "GET_VEHICLE_PED_IS_IN - Ped is not in a vehicle")
{
CVehicle *pVehicle = pPed->GetMyVehicle();
if (pVehicle)
{
CTheScripts::GetGUIDFromEntity(*pVehicle);
}
}
if (CGarages::IsPlayerEntirelyOutsideGarage(garageIndex, FindPlayerPed(), 0.0f))
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
const atVarString outside("Player is outside Garage");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), outside, true, 1.0f, 1.0f);
startPosition.y += _YInc;
grcDebugDraw::TextFontPop();
}
if (CGarages::IsPlayerEntirelyInsideGarage(garageIndex, FindPlayerPed(), 0.0f))
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
const atVarString inside("Player is inside Garage");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), inside, true, 1.0f, 1.0f);
startPosition.y += _YInc;
for (int i = 0; i < CGarages::aGarages[garageIndex].m_boxes.GetCount(); ++i)
{
if (CGarages::IsPlayerEntirelyInsideGarage(garageIndex, FindPlayerPed(), 0.0f, i))
{
const atVarString inside("Player is inside box %d",i);
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), inside, true, 1.0f, 1.0f);
startPosition.y += _YInc;
}
}
grcDebugDraw::TextFontPop();
}
else if (CGarages::IsPlayerPartiallyInsideGarage(garageIndex, FindPlayerPed()))
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
const atVarString partial("Player is partially inside Garage");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), partial, true, 1.0f, 1.0f);
startPosition.y += _YInc;
grcDebugDraw::TextFontPop();
}
if (garageIndex != -1 && ms_selectedBox < CGarages::aGarages[garageIndex].m_boxes.GetCount())
{
if (CGarages::IsPlayerPartiallyInsideGarage(garageIndex, FindPlayerPed(), ms_selectedBox))
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
const atVarString partial("Player is partially inside box %d", ms_selectedBox);
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), partial, true, 1.0f, 1.0f);
startPosition.y += _YInc;
grcDebugDraw::TextFontPop();
}
}
atArray<CEntity*> objects;
CGarages::FindAllObjectsInGarage(garageIndex, objects, ms_debugTestPeds, ms_debugTestVehicles, ms_debugTestObjects);
if (objects.GetCount() > 0)
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
const atVarString Heading("Objects Inside Garage");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), Heading, true, 1.0f, 1.0f);
startPosition.y += _YInc;
for (int i = 0; i < objects.GetCount(); ++i)
{
const atVarString object("%s", objects[i]->GetModelName());
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), object, true, 1.0f, 1.0f);
startPosition.y += _YInc;
}
grcDebugDraw::TextFontPop();
}
if (CGarages::IsAnyEntityEntirelyInsideGarage(garageIndex, ms_debugTestPeds, ms_debugTestVehicles, ms_debugTestObjects, 0.0f))
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
const atVarString partial("IsAnyEntityEntirelyInsideGarage - Yes");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), partial, true, 1.0f, 1.0f);
startPosition.y += _YInc;
grcDebugDraw::TextFontPop();
}
if (CGarages::aGarages[garageIndex].type == GARAGE_SAFEHOUSE_PARKING_ZONE)
{
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
u32 hash = CGarages::aGarages[garageIndex].name.GetHash();
bool enabled = object_commands::CommandIsSavingEnableForGarage(hash);
const atVarString partial("Saving of Vehicles Enabled - %s", enabled /*CGarages::aGarages[garageIndex].Flags.bSavingVehiclesEnabled */? "Yes" : "No");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), partial, true, 1.0f, 1.0f);
startPosition.y += _YInc;
grcDebugDraw::TextFontPop();
}
// Is Enclosed Garage
grcDebugDraw::TextFontPush(grcSetup::GetMiniFixedWidthFont());
{
const atVarString partial("Is Enclosed Garage - %s", CGarages::aGarages[garageIndex].m_IsEnclosed ? "Yes" : "No");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), partial, true, 1.0f, 1.0f);
startPosition.y += _YInc;
}
// Is MP Garage
{
const atVarString partial("Is MP Garage - %s", CGarages::aGarages[garageIndex].m_IsMPGarage ? "Yes" : "No");
grcDebugDraw::Text(startPosition, DD_ePCS_Pixels, CRGBA_White(), partial, true, 1.0f, 1.0f);
startPosition.y += _YInc;
}
grcDebugDraw::TextFontPop();
}
if (ms_bDisplayBoundingVolumePoints)
{
CPed *pPlayer = FindPlayerPed();
CEntity *pEntity;
if (pPlayer->GetPedConfigFlag(CPED_CONFIG_FLAG_InVehicle))
{
pEntity = pPlayer->GetMyVehicle();
}
else
{
pEntity = pPlayer;
}
if (ms_drawSmallSpheres)
{
Vector3 p0, p1, p2, p3;
CGarage::BuildQuadTestPoints(pEntity, p0, p1, p2, p3);
grcDebugDraw::Sphere(p0, 0.025f, Color32(0xFF, 0, 0, 0xFF));
grcDebugDraw::Sphere(p1, 0.025f, Color32( 0, 0xFF, 0, 0xFF));
grcDebugDraw::Sphere(p2, 0.025f, Color32(0, 0, 0xFF, 0xFF));
grcDebugDraw::Sphere(p3, 0.025f, Color32(0xFF, 0, 0xFF, 0xFF));
}
if (ms_drawLargeSpheres || ms_drawRectLines)
{
Vector3 p0, p1, p2, p3, p4, p5, p6, p7;
CGarage::BuildBoxTestPoints(pEntity, p0, p1, p2, p3, p4, p5, p6, p7);
if (ms_drawLargeSpheres)
{
grcDebugDraw::Sphere(p0, 0.05f, Color32(0xFF, 0, 0, 0xFF));
grcDebugDraw::Sphere(p1, 0.05f, Color32( 0, 0xFF, 0, 0xFF));
grcDebugDraw::Sphere(p2, 0.05f, Color32(0, 0, 0xFF, 0xFF));
grcDebugDraw::Sphere(p3, 0.05f, Color32(0xFF, 0, 0xFF, 0xFF));
grcDebugDraw::Sphere(p4, 0.05f, Color32(0x80, 0, 0, 0xFF));
grcDebugDraw::Sphere(p5, 0.05f, Color32( 0, 0x80, 0, 0xFF));
grcDebugDraw::Sphere(p6, 0.05f, Color32(0, 0, 0x80, 0xFF));
grcDebugDraw::Sphere(p7, 0.05f, Color32(0x80, 0, 0x80, 0xFF));
}
if (ms_drawRectLines)
{
Vector3 pA(p0.x, p0.y, (p0.z + p1.z)* 0.5f);
Vector3 pB(p5.x, p5.y, (p5.z + p6.z)* 0.5f);
Vector3 pC(p3.x, p3.y, (p3.z + p2.z)* 0.5f);
Vector3 pD(p4.x, p4.y, (p4.z + p7.z)* 0.5f);
grcDebugDraw::Sphere(pA, 0.025f, Color32(0xFF, 0, 0, 0x80));
grcDebugDraw::Sphere(pB, 0.025f, Color32( 0, 0xFF, 0, 0x80));
grcDebugDraw::Sphere(pC, 0.025f, Color32(0, 0, 0xFF, 0x80));
grcDebugDraw::Sphere(pD, 0.025f, Color32(0xFF, 0, 0xFF, 0x80));
Color32 colWhite = Color32(0xFF, 0xFF, 0xFF, 0xFF);
Color32 colRed = Color32(0xFF, 0, 0, 0xFF);
Color32 color = colWhite;
if (CGarages::IsLineIntersectingGarage(garageIndex, pA, pB, ms_selectedBox))
{
color = colRed;
}
grcDebugDraw::Line(pA, pB, color);
color = colWhite;
if (CGarages::IsLineIntersectingGarage(garageIndex, pC, pD, ms_selectedBox))
{
color = colRed;
}
grcDebugDraw::Line(pC, pD, color);
color = colWhite;
if (CGarages::IsLineIntersectingGarage(garageIndex, pA, pC, ms_selectedBox))
{
color = colRed;
}
grcDebugDraw::Line(pA, pC, color);
color = colWhite;
if (CGarages::IsLineIntersectingGarage(garageIndex, pB, pD, ms_selectedBox))
{
color = colRed;
}
grcDebugDraw::Line(pB, pD, color);
}
}
if (ms_drawBox2DTest && garageIndex != -1)
{
if (garageIndex < CGarages::aGarages.GetCount())
{
if (ms_selectedBox < CGarages::aGarages[garageIndex].m_boxes.GetCount())
{
CGarage::Box &box = CGarages::aGarages[garageIndex].m_boxes[ms_selectedBox];
// p2 ------------ p3
// | |
// | |
// | |
// | |
// | |
// p0 ------------ p1
Vector2 p0(box.BaseX, box.BaseY);
Vector2 p1(p0.x + box.Delta1X, p0.y + box.Delta1Y);
Vector2 p2(p0.x + box.Delta2X, p0.y + box.Delta2Y);
Vector2 p3(p1.x + box.Delta2X, p1.y + box.Delta2Y);
float z = (box.BaseZ + box.CeilingZ) * 0.5f;
// line p0 - p1
grcDebugDraw::Line(Vector3(p0.x, p0.y, z), Vector3(p1.x, p1.y, z), Color32(0x80, 0, 0, 0xFF));
// line p2 - p3
grcDebugDraw::Line(Vector3(p2.x, p2.y, z), Vector3(p3.x, p3.y, z), Color32(0, 0x80, 0, 0xFF));
// line p0 - p2
grcDebugDraw::Line(Vector3(p0.x, p0.y, z), Vector3(p2.x, p2.y, z), Color32(0, 0, 0x80, 0xFF));
// line p1 - p3
grcDebugDraw::Line(Vector3(p1.x, p1.y, z), Vector3(p3.x, p3.y, z), Color32(0x80, 0x80, 0, 0xFF));
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: DisplayGarages
// PURPOSE: debug draw, display all garages
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::DisplayGarages()
{
int garageIndex = -1;
for (s32 i = 0; i < CGarages::aGarages.GetCount(); ++i)
{
const CGarage* pG = &CGarages::aGarages[i];
for (int j = 0; j < pG->m_boxes.GetCount(); ++j)
{
const CGarage::Box &box = pG->m_boxes[j];
Color32 boxColor(0x80, 0x80, 0x80, 0xFF);
if (ms_pBoxListWindow)
{
garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex == i && ms_selectedBox == j)
{
ms_SelectedBoxPulse += 10;
boxColor = Color32(ms_SelectedBoxPulse, ms_SelectedBoxPulse, ms_SelectedBoxPulse, 0xff);
}
}
if (Vector2(box.BaseX - camInterface::GetPos().x, box.BaseY - camInterface::GetPos().y).Mag() < 100.0f)
{
// Lower area
grcDebugDraw::Line(Vector3(box.BaseX, box.BaseY, box.BaseZ),
Vector3(box.BaseX + box.Delta1X, box.BaseY + box.Delta1Y, box.BaseZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX + box.Delta1X, box.BaseY + box.Delta1Y, box.BaseZ),
Vector3(box.BaseX + box.Delta1X + box.Delta2X, box.BaseY + box.Delta1Y + box.Delta2Y, box.BaseZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX, box.BaseY, box.BaseZ),
Vector3(box.BaseX + box.Delta2X, box.BaseY + box.Delta2Y, box.BaseZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX + box.Delta2X, box.BaseY + box.Delta2Y, box.BaseZ),
Vector3(box.BaseX + box.Delta1X + box.Delta2X, box.BaseY + box.Delta1Y + box.Delta2Y, box.BaseZ),
boxColor);
// Ceiling area
grcDebugDraw::Line(Vector3(box.BaseX, box.BaseY, box.CeilingZ),
Vector3(box.BaseX + box.Delta1X, box.BaseY + box.Delta1Y, box.CeilingZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX + box.Delta1X, box.BaseY + box.Delta1Y, box.CeilingZ),
Vector3(box.BaseX + box.Delta1X + box.Delta2X, box.BaseY + box.Delta1Y + box.Delta2Y, box.CeilingZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX, box.BaseY, box.CeilingZ),
Vector3(box.BaseX + box.Delta2X, box.BaseY + box.Delta2Y, box.CeilingZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX + box.Delta2X, box.BaseY + box.Delta2Y, box.CeilingZ),
Vector3(box.BaseX + box.Delta1X + box.Delta2X, box.BaseY + box.Delta1Y + box.Delta2Y, box.CeilingZ),
boxColor);
// Four pillars
grcDebugDraw::Line(Vector3(box.BaseX, box.BaseY, box.BaseZ),
Vector3(box.BaseX, box.BaseY, box.CeilingZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX + box.Delta1X, box.BaseY + box.Delta1Y, box.BaseZ),
Vector3(box.BaseX + box.Delta1X, box.BaseY + box.Delta1Y, box.CeilingZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX + box.Delta2X, box.BaseY + box.Delta2Y, box.BaseZ),
Vector3(box.BaseX + box.Delta2X, box.BaseY + box.Delta2Y, box.CeilingZ),
boxColor);
grcDebugDraw::Line(Vector3(box.BaseX + box.Delta1X + box.Delta2X, box.BaseY + box.Delta1Y + box.Delta2Y, box.BaseZ),
Vector3(box.BaseX + box.Delta1X + box.Delta2X, box.BaseY + box.Delta1Y + box.Delta2Y, box.CeilingZ),
boxColor);
if (garageIndex == i && j == 0 && (ms_drawClearObjectsSphere || ms_drawCentreSphere))
{
float z = (box.CeilingZ - box.BaseZ) * 0.5f + box.BaseZ;
Vector2 delta1(box.Delta1X, box.Delta1Y);
Vector2 delta2(box.Delta2X, box.Delta2Y);
Vector2 base(box.BaseX, box.BaseY);
Vector2 pos2 = base + ((delta1 + delta2) * 0.5f);
Vector3 position(pos2.x, pos2.y, z);
float halfMag1 = delta1.Mag() * 0.5f;
float halfMag2 = delta2.Mag() * 0.5f;
float radius = Min(halfMag1, halfMag2);
if (ms_drawCentreSphere)
{
grcDebugDraw::Sphere(position, 0.1f, Color32(0xff, 0xff, 0xff, 0x20));
}
if (ms_drawClearObjectsSphere)
{
grcDebugDraw::Sphere(position, radius, Color32(0xff, 0x0, 0x0, 0x20));
}
}
// Display a crosshair at the doors' coordinate
if (garageIndex == i && pG->m_pDoorObject)
{
// Vector3 doorPos = VEC3V_TO_VECTOR3(pG->m_pDoorObject->GetTransform().GetPosition());
Vector3 doorPosMinX = pG->m_pDoorObject->TransformIntoWorldSpace(Vector3(-1.0f, 0.0f, 0.0f));
Vector3 doorPosMaxX = pG->m_pDoorObject->TransformIntoWorldSpace(Vector3(1.0f, 0.0f, 0.0f));
Vector3 doorPosMinY = pG->m_pDoorObject->TransformIntoWorldSpace(Vector3(0.0f, -1.0f, 0.0f));
Vector3 doorPosMaxY = pG->m_pDoorObject->TransformIntoWorldSpace(Vector3(0.0f, 1.0f, 0.0f));
Vector3 doorPosMinZ = pG->m_pDoorObject->TransformIntoWorldSpace(Vector3(0.0f, 0.0f, -1.0f));
Vector3 doorPosMaxZ = pG->m_pDoorObject->TransformIntoWorldSpace(Vector3(0.0f, 0.0f, 1.0f));
grcDebugDraw::Line(doorPosMinX, doorPosMaxX, Color32(0xff, 0x0, 0x0, 0xff));
grcDebugDraw::Line(doorPosMinY, doorPosMaxY, Color32(0x0, 0xff, 0x0, 0xff));
grcDebugDraw::Line(doorPosMinZ, doorPosMaxZ, Color32(0x0, 0x0, 0xff, 0xff));
}
if (garageIndex == i && j == 0)
{
// Display the name; type and state.
char debugStr[256];
sprintf(debugStr, "%s - Type:%d State:%d", pG->name.GetCStr(), pG->type, pG->state);
grcDebugDraw::Text(Vector3(box.BaseX + 0.5f * box.Delta1X, box.BaseY + 0.5f * box.Delta1Y, (box.BaseZ + box.CeilingZ) * 0.5f),
CRGBA(255, 255, 255, 255),
debugStr);
}
// draw bounding box
if (ms_bDisplayBoundingBoxes)
{
Vec3V bbMin(pG->MinX, pG->MinY, pG->MinZ);
Vec3V bbMax(pG->MaxX, pG->MaxY, pG->MaxZ);
grcDebugDraw::BoxAxisAligned(bbMin, bbMax, Color32(255, 0, 0), false);
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: CreateGarageAtCameraPosCB
// PURPOSE: creates a new box at camera position
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::CreateBoxAtCameraPosCB()
{
if (ms_pBoxListWindow)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
garage.m_boxes.Grow();
ms_selectedBox = garage.m_boxes.GetCount() - 1;
const Vector3& vPos = camInterface::GetPos();
CGarage::Box box;
box.BaseX = vPos.x;
box.BaseY = vPos.y;
box.BaseZ = vPos.z - DEFAULT_GARAGE_HEIGHT / 2.f;
box.Delta1X = DEFAULT_GARAGE_WIDTH;
box.Delta1Y = 0.0f;
box.Delta2X = 0.0f;
box.Delta2Y = DEFAULT_GARAGE_DEPTH;
box.CeilingZ = vPos.z + DEFAULT_GARAGE_HEIGHT / 2.f;
ms_bInteriorFlag = false;
ms_bExteriorFlag = false;
garage.UpdateSize(ms_selectedBox, box);
RefreshTweakVals();
}
}
}
namespace object_commands
{
void CommandClearGarage(int garageHash, bool bBroadcast);
void CommandClearObjectsFromGarage(int garageHash, bool vehicles, bool peds, bool objects, bool bBroadcast);
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: ClearSelectedGarageCB
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::ClearSelectedGarageCB()
{
if (ms_pBoxListWindow)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
object_commands::CommandClearGarage(garage.name.GetHash(), false);
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: ClearSelectedGarageOfPedsCB
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::ClearSelectedGarageOfPedsCB()
{
if (ms_pBoxListWindow)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
object_commands::CommandClearObjectsFromGarage(garage.name.GetHash(), false, true, false, false);
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: ClearSelectedGarageOfVehiclesCB
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::ClearSelectedGarageOfVehiclesCB()
{
if (ms_pBoxListWindow)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
object_commands::CommandClearObjectsFromGarage(garage.name.GetHash(), true, false, false, false);
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: ClearSelectedGarageOfObjectsCB
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::ClearSelectedGarageOfObjectsCB()
{
if (ms_pBoxListWindow)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
object_commands::CommandClearObjectsFromGarage(garage.name.GetHash(), false, false, true, false);
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: DeleteCurrentGarageCB
// PURPOSE: deletes the currently selected box
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::DeleteCurrentBoxCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
if (garage.m_boxes.GetCount() > 1)
{
garage.m_boxes.Delete(ms_selectedBox);
--ms_selectedBox;
ms_selectedBox = MAX(0, ms_selectedBox);
RefreshTweakVals();
ResetCurrentGarageBBCallback();
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: SelectedBoxCallback
// PURPOSE: Ensure selected box index is valid
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::SelectedBoxCallback()
{
if (ms_pBoxListWindow)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
if (ms_selectedBox >= garage.m_boxes.GetCount())
{
ms_selectedBox = garage.m_boxes.GetCount() - 1;
}
else if (ms_selectedBox < 0)
{
ms_selectedBox = 0;
}
RefreshTweakVals();
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: ResetCurrentGarageBBCallback
// PURPOSE:
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::ResetCurrentGarageBBCallback()
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex >= 0 && garageIndex < CGarages::aGarages.GetCount())
{
CGarage &garage = CGarages::aGarages[garageIndex];
garage.MinX = FLT_MAX;
garage.MaxX = -FLT_MAX;
garage.MinY = FLT_MAX;
garage.MaxY = -FLT_MAX;
garage.MinZ = FLT_MAX;
garage.MaxZ = -FLT_MAX;
for (int i = 0; i < garage.m_boxes.GetCount(); ++i)
{
garage.UpdateSize(i, garage.m_boxes[i]);
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: SnapVector2PerpendicularToVector1
// PURPOSE:
//////////////////////////////////////////////////////////////////////////
void SnapVector2PerpendicularToVector1(float v1x, float v1y, float *pV2x, float *PV2y)
{
Vector2 d1(v1x, v1y);
Vector2 d2(*pV2x, *PV2y);
float magD2 = d2.Mag();
d1.Normalize();
d2.Normalize();
Vector2 result(d1.y, -d1.x);
float dot = result.Dot(d2);
if (dot < 0.0f)
{
result.x = -d1.y;
result.y = d1.x;
}
result *= magD2;
*pV2x = result.x;
*PV2y = result.y;
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: SnapDelta2PerpendicularToDelta1CB
// PURPOSE:
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::SnapDelta2PerpendicularToDelta1CB()
{
SnapVector2PerpendicularToVector1(ms_delta1X, ms_delta1Y, &ms_delta2X, &ms_delta2Y);
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: SnapDelta1PerpendicularToDelta2VB
// PURPOSE:
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::SnapDelta1PerpendicularToDelta2CB()
{
SnapVector2PerpendicularToVector1(ms_delta2X, ms_delta2Y, &ms_delta1X, &ms_delta1Y);
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: UiGadgetsCB
// PURPOSE: construct / destroy any debug ui elements required
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::UiGadgetsCB()
{
if (ms_bDisplayAllGarages)
{
if (!ms_pBoxListWindow)
{
ms_pBoxListWindow = rage_new CUiGadgetSimpleListAndWindow("Garages", 700.0f, 60.0f, 150.0f, 40);
ms_pBoxListWindow->SetNumEntries(CGarages::aGarages.GetCount());
ms_pBoxListWindow->SetUpdateCellCB(UpdateBoxCellCB);
}
}
else
{
if (ms_pBoxListWindow)
{
delete ms_pBoxListWindow;
ms_pBoxListWindow = NULL;
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: UpdateBoxCellCB
// PURPOSE: callback to set cell contents for garage list
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::UpdateBoxCellCB(CUiGadgetText* pResult, u32 row, u32 UNUSED_PARAM(col), void* UNUSED_PARAM(extraCallbackData) )
{
if (row < CGarages::aGarages.GetCount())
{
pResult->SetString(CGarages::aGarages[row].name.GetCStr());
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: CreateGarageAtCameraPosCB
// PURPOSE: creates a new garage at camera position
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::CreateGarageAtCameraPosCB()
{
if (ms_pBoxListWindow)
{
static int newGarageIndex = 0;
const Vector3& vPos = camInterface::GetPos();
char garageName[GARAGE_NAME_MAX];
snprintf(garageName, GARAGE_NAME_MAX, "New garage %d", newGarageIndex);
garageName[GARAGE_NAME_MAX - 1] = '\0';
newGarageIndex++;
s32 idx = CGarages::AddOne(vPos.x, vPos.y, vPos.z - DEFAULT_GARAGE_HEIGHT / 2.f, DEFAULT_GARAGE_WIDTH, 0.f, 0.f, DEFAULT_GARAGE_DEPTH, vPos.z + DEFAULT_GARAGE_HEIGHT / 2.f, GARAGE_AMBIENT_PARKING, garageName, atHashString((u32)0), false, false, -1, -1);
--idx;
ms_pBoxListWindow->SetNumEntries(CGarages::aGarages.GetCount());
ms_pBoxListWindow->SetCurrentIndex(idx);
RefreshTweakVals();
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: DeleteCurrentGarageCB
// PURPOSE: deletes the currently selected garage
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::DeleteCurrentGarageCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1)
{
int garageIndex = ms_pBoxListWindow->GetCurrentIndex();
if (garageIndex < CGarages::aGarages.GetCount())
{
CGarages::aGarages.Delete(garageIndex);
--garageIndex;
garageIndex = MAX(0, garageIndex);
ms_pBoxListWindow->SetNumEntries(CGarages::aGarages.GetCount());
ms_pBoxListWindow->SetCurrentIndex(garageIndex);
RefreshTweakVals();
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: SetNameCB
// PURPOSE: sets a new name for the current selected garage
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::SetNameCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1 && ms_achCurrentGarageName[0] != '\0')
{
CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()].name.SetFromString(ms_achCurrentGarageName);
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: SetOwnerCB
// PURPOSE: sets a new owner for the current selected garage
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::SetOwnerCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1 && ms_achCurrentGarageName[0] != '\0')
{
u32 ownerNameHash = GetOwnerHashFromIDX(ms_OwnerSelection);
CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()].owner.SetHash(ownerNameHash);
}
}
// Note the IDX is local to the editor
u32 CGarageEditor::GetOwnerIDXFromHash(u32 hash)
{
if(hash != 0)
{
u32 playerhash = MI_PLAYERPED_PLAYER_ZERO.GetName().GetHash();
if(hash == playerhash)
{
return 1; // Michael
}
playerhash = MI_PLAYERPED_PLAYER_ONE.GetName().GetHash();
if(hash == playerhash)
{
return 2; // Franklin
}
playerhash = MI_PLAYERPED_PLAYER_TWO.GetName().GetHash();
if(hash == playerhash)
{
return 3; // Trevor
}
}
return 0; // Any
}
u32 CGarageEditor::GetOwnerHashFromIDX(u32 idx)
{
u32 hash = 0; // Any
switch(idx)
{
case 1:
{
// Michael
hash = MI_PLAYERPED_PLAYER_ZERO.GetName().GetHash();
break;
}
case 2:
{
// Franklin
hash = MI_PLAYERPED_PLAYER_ONE.GetName().GetHash();
break;
}
case 3:
{
// Trevor
hash = MI_PLAYERPED_PLAYER_TWO.GetName().GetHash();
break;
}
default:
{
break;
}
}
return hash;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// FUNCTION: MPGarageFlagSetCB
// PURPOSE:
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::MPGarageFlagSetCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1 && ms_achCurrentGarageName[0] != '\0')
{
CGarage& g = CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()];
g.m_IsMPGarage = ms_bMPGarageFlag;
if( !ms_bMPGarageFlag )
{
ExteriorFlagSetCB();
InteriorFlagSetCB();
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: EnclosedGarageFlagSetCB
// PURPOSE:
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::EnclosedGarageFlagSetCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1 && ms_achCurrentGarageName[0] != '\0')
{
CGarage& g = CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()];
g.m_IsEnclosed = ms_bEnclosedGarageFlag;
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: ExteriorFlagSetCB/InteriorFlagSetCB
// PURPOSE:
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::ExteriorFlagSetCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1 && ms_achCurrentGarageName[0] != '\0')
{
CGarage& g = CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()];
if( ms_bMPGarageFlag )
{
if( ms_bExteriorFlag )
{
if( g.m_InteriorBoxIDX == ms_selectedBox ) // Is this box also the interior box?
{
// Turn off interior flag on this box
ms_bInteriorFlag = false; // Does setting this call the callback? (NO)
InteriorFlagSetCB();
}
g.m_ExteriorBoxIDX = (s8)ms_selectedBox;
}
else
{
g.m_ExteriorBoxIDX = -1; // No index
}
}
else
{
ms_bExteriorFlag = false; // Balls, this change isn't reflected in the UI. Look into greying out?
g.m_ExteriorBoxIDX = -1; // No index
}
}
}
void CGarageEditor::InteriorFlagSetCB()
{
if (ms_pBoxListWindow && ms_pBoxListWindow->GetCurrentIndex() != -1 && ms_achCurrentGarageName[0] != '\0')
{
CGarage& g = CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()];
if( ms_bMPGarageFlag )
{
if( ms_bInteriorFlag )
{
if( g.m_ExteriorBoxIDX == ms_selectedBox ) // Is this box also the exterior box?
{
// Turn off interior flag on this box
ms_bExteriorFlag = false;
ExteriorFlagSetCB();
}
g.m_InteriorBoxIDX = (s8)ms_selectedBox;
}
else
{
g.m_InteriorBoxIDX = -1; // No index
}
}
else
{
ms_bInteriorFlag = false; // Balls, this change isn't reflected in the UI. Look into greying out?
g.m_InteriorBoxIDX = -1; // No index
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: RefreshTweakVals
// PURPOSE: update the tweak rag controls to current selected box
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::RefreshTweakVals()
{
if (ms_pBoxListWindow &&
ms_pBoxListWindow->GetCurrentIndex() != -1 &&
ms_pBoxListWindow->GetCurrentIndex() < CGarages::aGarages.GetCount())
{
CGarage& g = CGarages::aGarages[ms_pBoxListWindow->GetCurrentIndex()];
sprintf(ms_achCurrentGarageName, "%s", g.name.GetCStr());
if (ms_selectedBox >= g.m_boxes.GetCount())
{
ms_selectedBox = g.m_boxes.GetCount() - 1;
}
else if (ms_selectedBox < 0 )
{
ms_selectedBox = 0;
}
CGarage::Box &box = g.m_boxes[ms_selectedBox];
ms_baseX = box.BaseX;
ms_baseY = box.BaseY;
ms_baseZ = box.BaseZ;
ms_delta1X = box.Delta1X;
ms_delta1Y = box.Delta1Y;
ms_delta2X = box.Delta2X;
ms_delta2Y = box.Delta2Y;
ms_ceilingZ = box.CeilingZ;
ms_type = (s32)g.type;
ms_useLineIntersection = box.useLineIntersection;
if (g.m_permittedVehicleType == VEHICLE_TYPE_HELI)
{
ms_permittedVehicleType = 1;
}
else if (g.m_permittedVehicleType == VEHICLE_TYPE_BOAT)
{
ms_permittedVehicleType = 2;
}
else
{
ms_permittedVehicleType = 0;
}
// MP Garage flag
ms_bMPGarageFlag = g.m_IsMPGarage;
// Interior exterior boxes ID's
ms_bExteriorFlag = ms_bInteriorFlag = false;
if(g.m_ExteriorBoxIDX == ms_selectedBox)
{
ms_bExteriorFlag = true;
}
if(g.m_InteriorBoxIDX == ms_selectedBox)
{
ms_bInteriorFlag = true;
}
ms_startWithVehicleSavingEnable = g.Flags.bSavingVehiclesWasEnabledBeforeSave;
ms_vehicleSavingEnable = g.Flags.bSavingVehiclesEnabled;
ms_OwnerSelection = GetOwnerIDXFromHash(g.owner.GetHash());
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: Save
// PURPOSE: saves the meta file containing garage data, and updates ui
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::Save()
{
CGarages::Save();
if (ms_pBoxListWindow)
{
ms_pBoxListWindow->SetNumEntries(CGarages::aGarages.GetCount());
if (CGarages::aGarages.GetCount() > 0)
{
RefreshTweakVals();
}
}
}
//////////////////////////////////////////////////////////////////////////
// FUNCTION: Load
// PURPOSE: loads the meta file containing garage data, and updates ui
//////////////////////////////////////////////////////////////////////////
void CGarageEditor::Load()
{
CGarages::aGarages.Reset();
CGarages::NumSafeHousesRegistered = 0;
ms_selectedBox = 0;
CGarages::Load();
if (ms_pBoxListWindow)
{
ms_pBoxListWindow->SetNumEntries(CGarages::aGarages.GetCount());
if (CGarages::aGarages.GetCount() > 0)
{
ResetCurrentGarageBBCallback();
RefreshTweakVals();
}
}
}
#endif //__BANK