5820 lines
202 KiB
C++
5820 lines
202 KiB
C++
|
|
// Rage headers
|
|
#include "script/wrapper.h"
|
|
#include "physics/gtaInst.h"
|
|
#include "physics/sleep.h"
|
|
#include "fragment/instance.h"
|
|
#include "fragment/cache.h"
|
|
#include "fragment/cachemanager.h"
|
|
#include "fwanimation/animdirector.h"
|
|
#include "fwanimation/animmanager.h"
|
|
#include "fwmaths/Angle.h"
|
|
#include "fwmaths/vector.h"
|
|
#include "fwscene/search/SearchVolumes.h"
|
|
#include "fwscene/world/WorldLimits.h"
|
|
#include "phbound/boundcomposite.h"
|
|
|
|
// Framework headers
|
|
#include "fwdecorator/decoratorExtension.h"
|
|
|
|
// Game headers
|
|
#include "animation/AnimDefines.h"
|
|
#include "animation/MoveObject.h"
|
|
#include "audio/emitteraudioentity.h"
|
|
#include "camera/viewports/ViewportManager.h"
|
|
#include "camera/viewports/Viewport.h"
|
|
#include "control/replay/replay.h"
|
|
#include "control/replay/Entity/ObjectPacket.h"
|
|
#include "frontend/MiniMap.h"
|
|
#include "game/ModelIndices.h"
|
|
#include "ModelInfo/ModelInfo.h"
|
|
#include "ModelInfo/ModelInfo_Factories.h"
|
|
#include "network/Network.h"
|
|
#include "network/NetworkInterface.h"
|
|
#include "network/Objects/Entities/NetObjDoor.h"
|
|
#include "network/Objects/NetworkObjectPopulationMgr.h"
|
|
#include "Network/Live/NetworkTelemetry.h"
|
|
#include "network/events/NetworkEventTypes.h"
|
|
#include "network/general/NetworkUtil.h"
|
|
#include "objects/Door.h"
|
|
#include "objects/DummyObject.h"
|
|
#include "objects/ObjectPopulation.h"
|
|
#include "pathserver/PathServer.h"
|
|
#include "peds/Ped.h"
|
|
#include "pickups/Data/PickupIds.h"
|
|
#include "pickups/Data/PickupDataManager.h"
|
|
#include "pickups/Pickup.h"
|
|
#include "pickups/PickupPlacement.h"
|
|
#include "pickups/PickupManager.h"
|
|
#include "physics/WorldProbe/worldprobe.h"
|
|
#include "physics/physics.h"
|
|
#include "renderer/OcclusionQueries.h"
|
|
#include "renderer/Lights/LightEntity.h"
|
|
#include "scene/AnimatedBuilding.h"
|
|
#include "scene/entities/compEntity.h"
|
|
#include "scene/world/gameWorld.h"
|
|
#include "script/Handlers/GameScriptEntity.h"
|
|
#include "script/script.h"
|
|
#include "script/script_areas.h"
|
|
#include "script/script_cars_and_peds.h"
|
|
#include "script/script_debug.h"
|
|
#include "script/script_helper.h"
|
|
#include "shaders/CustomShaderEffectProp.h"
|
|
#include "security/plugins/scripthook.h"
|
|
#include "streaming/streaming.h"
|
|
#include "task/Combat/Cover/Cover.h"
|
|
#include "vehicles/vehicle.h"
|
|
#include "commands_interiors.h"
|
|
#include "commands_object.h"
|
|
#include "commands_misc.h"
|
|
#include "control/garages.h"
|
|
#include "fwscene/stores/staticboundsstore.h"
|
|
#include "Pickups/PickupRewards.h"
|
|
#include "weapons/Weapon.h"
|
|
#include "weapons/components/WeaponComponentFlashLight.h"
|
|
|
|
SCRIPT_OPTIMISATIONS ()
|
|
NETWORK_OPTIMISATIONS ()
|
|
|
|
#if __BANK
|
|
#include "fwdebug/picker.h"
|
|
extern bool sm_breakOnSelectedDoorSetState;
|
|
extern bool sm_logStateChangesForSelectedDoor;
|
|
extern int sm_debugDooorSystemEnumHash;
|
|
extern char sm_debugDooorSystemEnumString[CDoor::DEBUG_DOOR_STRING_LENGTH];
|
|
#define OutputScriptState(__doorEnumHash, __pString, ...) do { if (sm_logStateChangesForSelectedDoor && sm_debugDooorSystemEnumHash == __doorEnumHash) \
|
|
{ Displayf("Door Hash %s, %d", sm_debugDooorSystemEnumString, __doorEnumHash); \
|
|
Displayf(__pString, __VA_ARGS__); \
|
|
Displayf("Called by %s", CTheScripts::GetCurrentScriptNameAndProgramCounter());} } while(0)
|
|
#else
|
|
#define OutputScriptState(__doorEnumHash, __pString, ...)
|
|
#endif
|
|
|
|
#if __BANK
|
|
PARAM(netDebugCreatePortablePickup, "Output will echo the passed parameters, result, and frame times of CreatePortablePickup");
|
|
#endif
|
|
namespace object_commands
|
|
{
|
|
|
|
|
|
bool ObjectInAreaCheck( bool Do3dCheck, int iObjectID, const Vector3& vAreaFrom, const Vector3& vAreaTo, bool bHighlightArea )
|
|
{
|
|
const CObject *pObj;
|
|
|
|
float TargetX1, TargetY1, TargetZ1;
|
|
float TargetX2, TargetY2, TargetZ2;
|
|
float temp_float;
|
|
|
|
bool bResult = false;
|
|
|
|
pObj = CTheScripts::GetEntityToQueryFromGUID<CObject>(iObjectID);
|
|
if (!pObj)
|
|
{
|
|
return bResult;
|
|
}
|
|
TargetX1 = vAreaFrom.x;
|
|
TargetY1 = vAreaFrom.y;
|
|
|
|
if (Do3dCheck)
|
|
{
|
|
TargetZ1 = vAreaFrom.z;
|
|
TargetX2 = vAreaTo.x;
|
|
TargetY2 = vAreaTo.y;
|
|
TargetZ2 = vAreaTo.z;
|
|
|
|
if (TargetZ1 > TargetZ2)
|
|
{
|
|
temp_float = TargetZ1;
|
|
TargetZ1 = TargetZ2;
|
|
TargetZ2 = temp_float;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TargetZ1 = INVALID_MINIMUM_WORLD_Z;
|
|
TargetX2 = vAreaTo.x;
|
|
TargetY2 = vAreaTo.y;
|
|
TargetZ2 = TargetZ1;
|
|
}
|
|
|
|
if (TargetX1 > TargetX2)
|
|
{
|
|
temp_float = TargetX1;
|
|
TargetX1 = TargetX2;
|
|
TargetX2 = temp_float;
|
|
}
|
|
|
|
if (TargetY1 > TargetY2)
|
|
{
|
|
temp_float = TargetY1;
|
|
TargetY1 = TargetY2;
|
|
TargetY2 = temp_float;
|
|
}
|
|
|
|
const Vector3 ObjectPos = VEC3V_TO_VECTOR3(pObj->GetTransform().GetPosition());
|
|
|
|
// Check that the object is within the specified area
|
|
if (Do3dCheck)
|
|
{
|
|
if ((ObjectPos.x >= TargetX1) && (ObjectPos.x <= TargetX2)
|
|
&& (ObjectPos.y >= TargetY1) && (ObjectPos.y <= TargetY2)
|
|
&& (ObjectPos.z >= TargetZ1) && (ObjectPos.z <= TargetZ2))
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ((ObjectPos.x >= TargetX1) && (ObjectPos.x <= TargetX2)
|
|
&& (ObjectPos.y >= TargetY1) && (ObjectPos.y <= TargetY2))
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
|
|
if (bHighlightArea)
|
|
{
|
|
CScriptAreas::NewHighlightImportantArea(TargetX1, TargetY1, TargetZ1, TargetX2, TargetY2, TargetZ2, Do3dCheck, CALCULATION_OBJECT_IN_AREA);
|
|
}
|
|
|
|
if (CScriptDebug::GetDbgFlag())
|
|
{
|
|
if (Do3dCheck)
|
|
{
|
|
CScriptDebug::DrawDebugCube(TargetX1, TargetY1, TargetZ1, TargetX2, TargetY2, TargetZ2);
|
|
}
|
|
else
|
|
{
|
|
CScriptDebug::DrawDebugSquare(TargetX1, TargetY1, TargetX2, TargetY2);
|
|
}
|
|
}
|
|
return( bResult );
|
|
}
|
|
|
|
bool PointInAngledAreaCheck(bool Do3dCheck, const Vector3& vObjectPos, const Vector3& vCoords1, const Vector3& vCoords2, float DistanceFrom1To4, bool HighlightArea)
|
|
{
|
|
// Tests if the given point is contained within a non-axis aligned rectangle which is defined by the midpoints of two parallel edges
|
|
// and the length of those sides:
|
|
//
|
|
// <--AreaWidth-->
|
|
// srcVecCoors1
|
|
// -------x-------
|
|
// | |
|
|
// | |
|
|
// -------x-------
|
|
// srcVecCoors2
|
|
|
|
float TargetX1, TargetY1, TargetZ1;
|
|
float TargetX2, TargetY2, TargetZ2;
|
|
float TargetX3, TargetY3; // , TargetZ3;
|
|
float TargetX4, TargetY4; // , TargetZ4;
|
|
|
|
float temp_float;
|
|
|
|
bool bResult = false;
|
|
|
|
float RadiansBetweenFirstTwoPoints;
|
|
float RadiansBetweenPoints1and4;
|
|
float TestDistance;
|
|
|
|
Vector2 vec1To2, vec1To4, vec1ToObject;
|
|
|
|
float DistanceFrom1To2, DistanceFrom1To4Test;
|
|
|
|
TargetX1 = vCoords1.x;
|
|
TargetY1 = vCoords1.y;
|
|
|
|
if (Do3dCheck)
|
|
{
|
|
TargetZ1 = vCoords1.z;
|
|
TargetX2 = vCoords2.x;
|
|
TargetY2 = vCoords2.y;
|
|
TargetZ2 = vCoords2.z;
|
|
|
|
if (TargetZ1 > TargetZ2)
|
|
{
|
|
temp_float = TargetZ1;
|
|
TargetZ1 = TargetZ2;
|
|
TargetZ2 = temp_float;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TargetZ1 = 0.0f;
|
|
TargetX2 = vCoords2.x;
|
|
TargetY2 = vCoords2.y;
|
|
TargetZ2 = 0.0f;
|
|
}
|
|
|
|
RadiansBetweenFirstTwoPoints = fwAngle::GetRadianAngleBetweenPoints(TargetX1, TargetY1, TargetX2, TargetY2);
|
|
RadiansBetweenPoints1and4 = RadiansBetweenFirstTwoPoints + (PI / 2);
|
|
|
|
while (RadiansBetweenPoints1and4 < 0.0f)
|
|
{
|
|
RadiansBetweenPoints1and4 += (2 * PI);
|
|
}
|
|
|
|
while (RadiansBetweenPoints1and4 > (2 * PI))
|
|
{
|
|
RadiansBetweenPoints1and4 -= (2 * PI);
|
|
}
|
|
|
|
float fSinResult = rage::Sinf(RadiansBetweenPoints1and4);
|
|
float fCosResult = rage::Cosf(RadiansBetweenPoints1and4);
|
|
TargetX3 = (0.5f*DistanceFrom1To4 * fSinResult) + TargetX2;
|
|
TargetY3 = (0.5f*DistanceFrom1To4 * -fCosResult) + TargetY2;
|
|
|
|
TargetX4 = (0.5f*DistanceFrom1To4 * fSinResult) + TargetX1;
|
|
TargetY4 = (0.5f*DistanceFrom1To4 * -fCosResult) + TargetY1;
|
|
|
|
// Modify Target1 and Target2 to be at the opposite corners of the rectangle from 3 and 4; they are currently defining
|
|
// the midpoints of two sides.
|
|
TargetX1 = TargetX1 - (0.5f*DistanceFrom1To4 * fSinResult);
|
|
TargetY1 = TargetY1 - (0.5f*DistanceFrom1To4 * -fCosResult);
|
|
TargetX2 = TargetX2 - (0.5f*DistanceFrom1To4 * fSinResult);
|
|
TargetY2 = TargetY2 - (0.5f*DistanceFrom1To4 * -fCosResult);
|
|
|
|
vec1To2 = Vector2((TargetX2 - TargetX1), (TargetY2 - TargetY1));
|
|
vec1To4 = Vector2((TargetX4 - TargetX1), (TargetY4 - TargetY1));
|
|
|
|
DistanceFrom1To2 = vec1To2.Mag();
|
|
DistanceFrom1To4Test = vec1To4.Mag();
|
|
|
|
|
|
bResult = FALSE;
|
|
|
|
vec1ToObject = Vector2((vObjectPos.x - TargetX1), (vObjectPos.y - TargetY1));
|
|
|
|
vec1To2.Normalize();
|
|
TestDistance = vec1ToObject.Dot(vec1To2);
|
|
|
|
// Check that the object is within the specified area
|
|
if ((TestDistance >= 0.0f)
|
|
&& (TestDistance <= DistanceFrom1To2))
|
|
{
|
|
vec1To4.Normalize();
|
|
TestDistance = vec1ToObject.Dot(vec1To4);
|
|
|
|
if ((TestDistance >= 0.0f)
|
|
&& (TestDistance <= DistanceFrom1To4Test))
|
|
{
|
|
if (Do3dCheck)
|
|
{
|
|
if ((vObjectPos.z >= TargetZ1) && (vObjectPos.z <= TargetZ2))
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (HighlightArea)
|
|
{
|
|
if (Do3dCheck)
|
|
{
|
|
// float CentreZ = (TargetZ1 + TargetZ2) / 2.0f;
|
|
|
|
CScriptAreas::HighlightImportantAngledArea( (u32)(CTheScripts::GetCurrentGtaScriptThread()->GetIDForThisLineInThisThread()),
|
|
TargetX1, TargetY1,
|
|
TargetX2, TargetY2,
|
|
TargetX3, TargetY3,
|
|
TargetX4, TargetY4,
|
|
TargetZ1);
|
|
}
|
|
else
|
|
{
|
|
CScriptAreas::HighlightImportantAngledArea( (u32)(CTheScripts::GetCurrentGtaScriptThread()->GetIDForThisLineInThisThread()),
|
|
TargetX1, TargetY1,
|
|
TargetX2, TargetY2,
|
|
TargetX3, TargetY3,
|
|
TargetX4, TargetY4,
|
|
INVALID_MINIMUM_WORLD_Z);
|
|
}
|
|
}
|
|
|
|
|
|
if (CScriptDebug::GetDbgFlag())
|
|
{
|
|
if (Do3dCheck)
|
|
{
|
|
CScriptDebug::DrawDebugAngledCube(TargetX1, TargetY1, TargetZ1, TargetX2, TargetY2, TargetZ2, TargetX3, TargetY3, TargetX4, TargetY4);
|
|
}
|
|
else
|
|
{
|
|
CScriptDebug::DrawDebugAngledSquare(TargetX1, TargetY1, TargetX2, TargetY2, TargetX3, TargetY3, TargetX4, TargetY4);
|
|
}
|
|
}
|
|
return(bResult);
|
|
}
|
|
|
|
void CommandSetActivateObjectPhysicsAsSoonAsItIsUnfrozen(int ObjectIndex, bool bActivatePhysicsWhenUnfrozen)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
if (bActivatePhysicsWhenUnfrozen)
|
|
{
|
|
pObj->m_nObjectFlags.bActivatePhysicsAsSoonAsUnfrozen = true;
|
|
}
|
|
else
|
|
{
|
|
pObj->m_nObjectFlags.bActivatePhysicsAsSoonAsUnfrozen = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// bCalledByScriptCommand will be false if this function is called when loading from memory card
|
|
// PoolIndex is only used when loading from the memory card. It will be -1 in all other cases
|
|
void ObjectCreationFunction(int ObjectModelHashKey, float NewX, float NewY, float NewZ, bool bWithZOffset, bool bCalledByScriptCommand, s32 PoolIndex, int& iNewObjectIndex, bool bRegisterAsNetworkObject, bool bScriptHostObject, bool bForceToBeObject)
|
|
{
|
|
iNewObjectIndex = 0;
|
|
fwModelId ObjectModelId;
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) ObjectModelHashKey, &ObjectModelId); // ignores return value
|
|
|
|
// non-networked objects should always be treated as client objects
|
|
if (!bRegisterAsNetworkObject)
|
|
bScriptHostObject = false;
|
|
|
|
if (!SCRIPT_VERIFY (ObjectModelId.IsValid(), "ObjectCreationFunction - this is not a valid model index"))
|
|
{
|
|
return;
|
|
}
|
|
if (!SCRIPT_VERIFY ((rage::Abs(NewX)< WORLDLIMITS_XMAX) &&(rage::Abs(NewY)< WORLDLIMITS_YMAX) && (rage::Abs(NewZ)< WORLDLIMITS_ZMAX), "ObjectCreationFunction - Trying to create an object outside the world bounds"))
|
|
{
|
|
return;
|
|
}
|
|
if (!SCRIPT_VERIFY(!CNetwork::IsGameInProgress() || !bRegisterAsNetworkObject || CTheScripts::GetCurrentGtaScriptHandlerNetwork() || bCalledByScriptCommand, "ObjectCreationFunction - Non-networked scripts that are safe to run during the network game cannot create networked entities"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
CBaseModelInfo* pModel = CModelInfo::GetBaseModelInfo(ObjectModelId);
|
|
|
|
if (!SCRIPT_VERIFY (pModel, "ObjectCreationFunction - Couldn't find Model Info"))
|
|
{
|
|
return;
|
|
}
|
|
if (!SCRIPT_VERIFY_TWO_STRINGS (pModel->GetIsTypeObject(), "%s:ObjectCreationFunction - Model isn't type object", pModel->GetModelName()))
|
|
{
|
|
return;
|
|
}
|
|
if (bScriptHostObject && (CTheScripts::GetCurrentGtaScriptHandlerNetwork() && CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()))
|
|
{
|
|
if (!SCRIPT_VERIFY (CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()->IsHostLocal(), "ObjectCreationFunction - Non-host machines cannot create host objects"))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
if (!SCRIPT_VERIFY (!(pModel->GetUsesDoorPhysics() && !bForceToBeObject && NetworkInterface::IsGameInProgress()), "ObjectCreationFunction - Cannot create doors in MP, it is currently not supported. Set ForceToBeObject to TRUE to force this door to be an object and prevent this assert"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!SCRIPT_VERIFY (!(CObjectPopulation::IsBlacklistedForMP(pModel->GetModelNameHash()) && NetworkInterface::IsGameInProgress()), "ObjectCreationFunction - Cannot create blacklisted objects in MP, it is currently not permitted."))
|
|
{
|
|
return;
|
|
}
|
|
|
|
#if __DEV
|
|
printf("creating object %s, by script %s \n", pModel->GetModelName(), CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
#endif
|
|
|
|
// don't network objects created during a cutscene
|
|
if (!NetworkInterface::AreCutsceneEntitiesNetworked() && CTheScripts::GetCurrentGtaScriptHandlerNetwork() && CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetInMPCutscene())
|
|
{
|
|
if (scriptVerifyf(NetworkInterface::IsInMPCutscene(), "Script cutscene flag still set when not in a cutscene"))
|
|
{
|
|
bRegisterAsNetworkObject = false;
|
|
}
|
|
else
|
|
{
|
|
CTheScripts::GetCurrentGtaScriptHandlerNetwork()->SetInMPCutscene(false);
|
|
}
|
|
}
|
|
|
|
//Create the input.
|
|
CObjectPopulation::CreateObjectInput input(ObjectModelId, ENTITY_OWNEDBY_SCRIPT, false);
|
|
input.m_bInitPhys = true;
|
|
input.m_bClone = bRegisterAsNetworkObject;
|
|
input.m_bForceClone = bRegisterAsNetworkObject;
|
|
input.m_iPoolIndex = (PoolIndex >= 0) ? PoolIndex : -1;
|
|
input.m_bForceObjectType = bForceToBeObject;
|
|
|
|
CObject* pObject = CObjectPopulation::CreateObject(input);
|
|
|
|
if (!SCRIPT_VERIFY (pObject, "ObjectCreationFunction - Couldn't create a new object"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
REPLAY_ONLY(CReplayMgr::RecordObject(pObject));
|
|
|
|
pObject->m_nPhysicalFlags.bNotToBeNetworked = !bRegisterAsNetworkObject;
|
|
|
|
if (NetworkInterface::IsGameInProgress() && bRegisterAsNetworkObject)
|
|
{
|
|
scriptAssertf(pObject->GetNetworkObject(), "ObjectCreationFunction - Ran out of network objects for this object");
|
|
}
|
|
|
|
if (NewZ <= INVALID_MINIMUM_WORLD_Z)
|
|
{
|
|
NewZ = WorldProbe::FindGroundZForCoord(TOP_SURFACE, NewX, NewY);
|
|
}
|
|
|
|
if (bWithZOffset)
|
|
{
|
|
NewZ += pObject->GetDistanceFromCentreOfMassToBaseOfModel();
|
|
}
|
|
|
|
pObject->SetPosition(Vector3(NewX, NewY, NewZ));
|
|
pObject->SetHeading(0.0f);
|
|
|
|
// Add Object to world after its position has been set
|
|
CGameWorld::Add(pObject, CGameWorld::OUTSIDE );
|
|
pObject->GetPortalTracker()->RequestRescanNextUpdate();
|
|
pObject->GetPortalTracker()->Update(VEC3V_TO_VECTOR3(pObject->GetTransform().GetPosition()));
|
|
|
|
pObject->CreateDrawable();
|
|
|
|
CScriptEntities::ClearSpaceForMissionEntity(pObject);
|
|
iNewObjectIndex = CTheScripts::GetGUIDFromEntity(*pObject);
|
|
|
|
if (bCalledByScriptCommand && CTheScripts::GetCurrentGtaScriptThread())
|
|
{
|
|
pObject->GetLodData().SetResetDisabled(true);
|
|
CTheScripts::RegisterEntity(pObject, bScriptHostObject, bRegisterAsNetworkObject);
|
|
}
|
|
|
|
#if GTA_REPLAY
|
|
// HACK for TV Static Object (B*2240576)
|
|
if( pModel && pModel->GetModelNameHash() == ATSTRINGHASH("Prop_TT_screenstatic",0xe2e039bc) )
|
|
{
|
|
CReplayMgr::RecordObject(pObject);
|
|
}
|
|
// HACK
|
|
#endif //GTA_REPLAY
|
|
|
|
// B*7009579: HACK for Ammu-Nation gun selection wall going bright during the day:
|
|
if(pObject->GetModelNameHash() == ATSTRINGHASH("ch_prop_board_wpnwall_02a", 0x0A3C70FA))
|
|
pObject->SetNaturalAmbientScale(0);
|
|
}
|
|
|
|
int CommandCreateObject(int ObjectModelHashKey, const scrVector & scrVecNewCoors, bool bRegisterAsNetworkObject, bool bScriptHostObject, bool bForceToBeObject)
|
|
{
|
|
int iNewObjectIndex;
|
|
|
|
Vector3 vNewCoors = Vector3 (scrVecNewCoors);
|
|
|
|
scriptAssertf( (rage::Abs(vNewCoors.x) > 0.05f) || (rage::Abs(vNewCoors.y) > 0.05f) || vNewCoors.z > 100.0f, "CREATE_OBJECT. Don't create objects at (0,0). Create them at their final destination instead" );
|
|
|
|
ObjectCreationFunction(ObjectModelHashKey, vNewCoors.x, vNewCoors.y, vNewCoors.z, true, true, -1, iNewObjectIndex, bRegisterAsNetworkObject, bScriptHostObject, bForceToBeObject);
|
|
|
|
return iNewObjectIndex;
|
|
}
|
|
|
|
int CommandCreateObjectNoOffset(int ObjectModelHashKey, const scrVector & scrVecNewCoors, bool bRegisterAsNetworkObject, bool bScriptHostObject, bool bForceToBeObject )
|
|
{
|
|
int iNewObjectIndex;
|
|
|
|
Vector3 vNewCoors = Vector3 (scrVecNewCoors);
|
|
|
|
scriptAssertf( (rage::Abs(vNewCoors.x) > 0.05f) || (rage::Abs(vNewCoors.y) > 0.05f) || vNewCoors.z > 100.0f, "CREATE_OBJECT_NO_OFFSET. Don't create objects at (0,0). Create them at their final destination instead" );
|
|
SCRIPT_CHECK_CALLING_FUNCTION
|
|
ObjectCreationFunction(ObjectModelHashKey, vNewCoors.x, vNewCoors.y, vNewCoors.z, false, true, -1, iNewObjectIndex, bRegisterAsNetworkObject, bScriptHostObject, bForceToBeObject);
|
|
|
|
return iNewObjectIndex;
|
|
}
|
|
|
|
void DeleteScriptObject(CObject *pObject)
|
|
{
|
|
if (scriptVerifyf(pObject, "DeleteScriptObject - object doesn't exist"))
|
|
{
|
|
CScriptEntityExtension* pExtension = pObject->GetExtension<CScriptEntityExtension>();
|
|
|
|
// Maybe it's okay to allow these objects to be deleted now. As soon as they are grabbed from the world, all ties are broken.
|
|
// I no longer keep a pointer to the related dummy object.
|
|
if (SCRIPT_VERIFY(pExtension, "DeleteScriptObject - The object is not a script entity") &&
|
|
(SCRIPT_VERIFY(pExtension->GetScriptObjectWasGrabbedFromTheWorld() == false, "DeleteScriptObject - can't delete an object that was grabbed from the world")) )
|
|
{
|
|
CObjectPopulation::DestroyObject(pObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandDeleteObject(int &ObjectIndex)
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex, CTheScripts::GUID_ASSERT_FLAG_NOT_CLONE);
|
|
|
|
if (pObject && !NetworkUtils::IsNetworkCloneOrMigrating(pObject))
|
|
{
|
|
CScriptEntityExtension* pExtension = pObject->GetExtension<CScriptEntityExtension>();
|
|
|
|
if (SCRIPT_VERIFY(pExtension, "DELETE_OBJECT - The object is not a script entity") &&
|
|
SCRIPT_VERIFY(pExtension->GetScriptHandler()==CTheScripts::GetCurrentGtaScriptHandler(), "DELETE_OBJECT - The object was not created by this script"))
|
|
{
|
|
DeleteScriptObject(pObject);
|
|
}
|
|
}
|
|
|
|
ObjectIndex = 0;
|
|
}
|
|
|
|
bool CommandPlaceObjectOnGroundProperly(int ObjectIndex)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
if(pObject)
|
|
{
|
|
bool ret = pObject->PlaceOnGroundProperly();
|
|
if(!ret)
|
|
{
|
|
pObject->SetIsFixedWaitingForCollision(true);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CommandPlaceObjectOnGroundOrObjectProperly(int ObjectIndex)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
if(pObject)
|
|
{
|
|
bool ret = pObject->PlaceOnGroundProperly( 10.0f, true, 0.0f, false, false, NULL, true );
|
|
if(!ret)
|
|
{
|
|
pObject->SetIsFixedWaitingForCollision(true);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
scrVector CommandGetSafePickupCoords(const scrVector & scrVecInCoors, float minDist, float maxDist )
|
|
{
|
|
Vector3 srcPos( scrVecInCoors );
|
|
bool bGroundLoaded = g_StaticBoundsStore.GetBoxStreamer().HasLoadedAboutPos(VECTOR3_TO_VEC3V(srcPos), fwBoxStreamerAsset::FLAG_STATICBOUNDS_MOVER);
|
|
if(bGroundLoaded)
|
|
{
|
|
CPickupManager::CPickupPositionInfo pos( srcPos );
|
|
if ( !scriptVerifyf( minDist < maxDist, "GET_SAFE_PICKUP_COORDS - swapping min and max values as wrong way round [%f - %f]",
|
|
minDist, maxDist ) )
|
|
{
|
|
float tmp(minDist);
|
|
minDist = maxDist;
|
|
maxDist = tmp;
|
|
}
|
|
pos.m_MinDist = minDist;
|
|
pos.m_MaxDist = maxDist;
|
|
CPickupManager::CalculateDroppedPickupPosition(pos, true);
|
|
|
|
return pos.m_Pos;
|
|
}
|
|
|
|
aiWarningf("Ground collision has not streamed in.");
|
|
return srcPos;
|
|
}
|
|
|
|
void CommandAddExtendedPickupProbeArea(const scrVector& position, float radius)
|
|
{
|
|
if(NetworkInterface::IsGameInProgress())
|
|
{
|
|
#if !__FINAL
|
|
scrThread::PrePrintStackTrace();
|
|
scriptDebugf1("%s : ADD_EXTENDED_PICKUP_PROBE_AREA called", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
#endif
|
|
|
|
Vector3 areaPosition(position);
|
|
#if ENABLE_NETWORK_LOGGING
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "ADD_EXTENDED_PICKUP_PROBE_AREA", "x:%.f, y:%.f, z:%.f", areaPosition.GetX(), areaPosition.GetY(), areaPosition.GetZ());
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
log.WriteDataValue("Script", "%.f", radius);
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
|
|
if(CPickup::AddExtendedProbeArea(areaPosition, radius))
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
log.WriteDataValue("Result", "%s", "Successful");
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
}
|
|
else
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
log.WriteDataValue("Result", "%s", "Failed");
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandClearExtendedPickupProbeAreas()
|
|
{
|
|
#if !__FINAL
|
|
scrThread::PrePrintStackTrace();
|
|
scriptDebugf1("%s : CLEAR_EXTENDED_PICKUP_PROBE_AREAS called", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
#endif
|
|
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if(NetworkInterface::IsGameInProgress())
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "CLEAR_EXTENDED_PICKUP_PROBE_AREAS", "");
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
}
|
|
#endif
|
|
CPickup::ClearExtendedProbeAreas();
|
|
}
|
|
|
|
// temp function to convert the old pickup types to the new hashes. Remove once the scripts are all using the hashes.
|
|
int ConvertOldPickupTypeToHash(int PickupType)
|
|
{
|
|
if (PickupType >=0 && PickupType < NUM_PICKUP_TYPES)
|
|
{
|
|
switch (PickupType)
|
|
{
|
|
case PICKUP_HEALTH_STANDARD_TYPE:
|
|
return PICKUP_HEALTH_STANDARD;
|
|
case PICKUP_ARMOUR_STANDARD_TYPE:
|
|
return PICKUP_ARMOUR_STANDARD;
|
|
case PICKUP_MONEY_VARIABLE_TYPE:
|
|
return PICKUP_MONEY_VARIABLE;
|
|
case PICKUP_MONEY_CASE_TYPE:
|
|
return PICKUP_MONEY_CASE;
|
|
case PICKUP_MONEY_WALLET_TYPE:
|
|
return PICKUP_MONEY_WALLET;
|
|
case PICKUP_MONEY_PURSE_TYPE:
|
|
return PICKUP_MONEY_PURSE;
|
|
case PICKUP_MONEY_DEP_BAG_TYPE:
|
|
return PICKUP_MONEY_DEP_BAG;
|
|
case PICKUP_MONEY_MED_BAG_TYPE:
|
|
return PICKUP_MONEY_MED_BAG;
|
|
case PICKUP_MONEY_PAPER_BAG_TYPE:
|
|
return PICKUP_MONEY_PAPER_BAG;
|
|
case PICKUP_MONEY_SECURITY_CASE_TYPE:
|
|
return PICKUP_MONEY_SECURITY_CASE;
|
|
case PICKUP_CUSTOM_SCRIPT_TYPE:
|
|
return PICKUP_CUSTOM_SCRIPT;
|
|
case PICKUP_HANDCUFF_KEY_TYPE:
|
|
return PICKUP_HANDCUFF_KEY;
|
|
case PICKUP_CAMERA_TYPE:
|
|
return PICKUP_CAMERA;
|
|
case PICKUP_PORTABLE_PACKAGE_TYPE:
|
|
return PICKUP_PORTABLE_PACKAGE;
|
|
|
|
// Weapons
|
|
case PICKUP_WEAPON_PISTOL_TYPE:
|
|
return PICKUP_WEAPON_PISTOL;
|
|
case PICKUP_WEAPON_COMBATPISTOL_TYPE:
|
|
return PICKUP_WEAPON_COMBATPISTOL;
|
|
case PICKUP_WEAPON_PISTOL50_TYPE:
|
|
return PICKUP_WEAPON_PISTOL50;
|
|
case PICKUP_WEAPON_APPISTOL_TYPE:
|
|
return PICKUP_WEAPON_APPISTOL;
|
|
case PICKUP_WEAPON_MICROSMG_TYPE:
|
|
return PICKUP_WEAPON_MICROSMG;
|
|
case PICKUP_WEAPON_SMG_TYPE:
|
|
return PICKUP_WEAPON_SMG;
|
|
case PICKUP_WEAPON_ASSAULTSMG_TYPE:
|
|
return PICKUP_WEAPON_ASSAULTSMG;
|
|
case PICKUP_WEAPON_ASSAULTRIFLE_TYPE:
|
|
return PICKUP_WEAPON_ASSAULTRIFLE;
|
|
case PICKUP_WEAPON_CARBINERIFLE_TYPE:
|
|
return PICKUP_WEAPON_CARBINERIFLE;
|
|
case PICKUP_WEAPON_HEAVYRIFLE_TYPE:
|
|
return PICKUP_WEAPON_HEAVYRIFLE;
|
|
case PICKUP_WEAPON_ADVANCEDRIFLE_TYPE:
|
|
return PICKUP_WEAPON_ADVANCEDRIFLE;
|
|
case PICKUP_WEAPON_MG_TYPE:
|
|
return PICKUP_WEAPON_MG;
|
|
case PICKUP_WEAPON_COMBATMG_TYPE:
|
|
return PICKUP_WEAPON_COMBATMG;
|
|
case PICKUP_WEAPON_ASSAULTMG_TYPE:
|
|
return PICKUP_WEAPON_ASSAULTMG;
|
|
case PICKUP_WEAPON_PUMPSHOTGUN_TYPE:
|
|
return PICKUP_WEAPON_PUMPSHOTGUN;
|
|
case PICKUP_WEAPON_SAWNOFFSHOTGUN_TYPE:
|
|
return PICKUP_WEAPON_SAWNOFFSHOTGUN;
|
|
case PICKUP_WEAPON_BULLPUPSHOTGUN_TYPE:
|
|
return PICKUP_WEAPON_BULLPUPSHOTGUN;
|
|
case PICKUP_WEAPON_ASSAULTSHOTGUN_TYPE:
|
|
return PICKUP_WEAPON_ASSAULTSHOTGUN;
|
|
case PICKUP_WEAPON_SNIPERRIFLE_TYPE:
|
|
return PICKUP_WEAPON_SNIPERRIFLE;
|
|
case PICKUP_WEAPON_ASSAULTSNIPER_TYPE:
|
|
return PICKUP_WEAPON_ASSAULTSNIPER;
|
|
case PICKUP_WEAPON_HEAVYSNIPER_TYPE:
|
|
return PICKUP_WEAPON_HEAVYSNIPER;
|
|
case PICKUP_WEAPON_GRENADELAUNCHER_TYPE:
|
|
return PICKUP_WEAPON_GRENADELAUNCHER;
|
|
case PICKUP_WEAPON_RPG_TYPE:
|
|
return PICKUP_WEAPON_RPG;
|
|
case PICKUP_WEAPON_MINIGUN_TYPE:
|
|
return PICKUP_WEAPON_MINIGUN;
|
|
case PICKUP_WEAPON_GRENADE_TYPE:
|
|
return PICKUP_WEAPON_GRENADE;
|
|
case PICKUP_WEAPON_SMOKEGRENADE_TYPE:
|
|
return PICKUP_WEAPON_SMOKEGRENADE;
|
|
case PICKUP_WEAPON_STICKYBOMB_TYPE:
|
|
return PICKUP_WEAPON_STICKYBOMB;
|
|
case PICKUP_WEAPON_MOLOTOV_TYPE:
|
|
return PICKUP_WEAPON_MOLOTOV;
|
|
case PICKUP_WEAPON_STUNGUN_TYPE:
|
|
return PICKUP_WEAPON_STUNGUN;
|
|
case PICKUP_WEAPON_RUBBERGUN_TYPE:
|
|
return PICKUP_WEAPON_RUBBERGUN;
|
|
case PICKUP_WEAPON_PROGRAMMABLEAR_TYPE:
|
|
return PICKUP_WEAPON_PROGRAMMABLEAR;
|
|
case PICKUP_WEAPON_FIREEXTINGUISHER_TYPE:
|
|
return PICKUP_WEAPON_FIREEXTINGUISHER;
|
|
case PICKUP_WEAPON_PETROLCAN_TYPE:
|
|
return PICKUP_WEAPON_PETROLCAN;
|
|
case PICKUP_WEAPON_LOUDHAILER_TYPE:
|
|
return PICKUP_WEAPON_LOUDHAILER;
|
|
#if LASSO_WEAPON_EXISTS
|
|
case PICKUP_WEAPON_LASSO_TYPE:
|
|
return PICKUP_WEAPON_LASSO;
|
|
#endif
|
|
case PICKUP_WEAPON_KNIFE_TYPE:
|
|
return PICKUP_WEAPON_KNIFE;
|
|
case PICKUP_WEAPON_NIGHTSTICK_TYPE:
|
|
return PICKUP_WEAPON_NIGHTSTICK;
|
|
case PICKUP_WEAPON_HAMMER_TYPE:
|
|
return PICKUP_WEAPON_HAMMER;
|
|
case PICKUP_WEAPON_BAT_TYPE:
|
|
return PICKUP_WEAPON_BAT;
|
|
case PICKUP_WEAPON_GOLFCLUB_TYPE:
|
|
return PICKUP_WEAPON_GOLFCLUB;
|
|
|
|
// vehicle pickups
|
|
case PICKUP_VEHICLE_HEALTH_STANDARD_TYPE:
|
|
return PICKUP_VEHICLE_HEALTH_STANDARD;
|
|
case PICKUP_VEHICLE_ARMOUR_STANDARD_TYPE:
|
|
return PICKUP_VEHICLE_ARMOUR_STANDARD;
|
|
case PICKUP_VEHICLE_WEAPON_PISTOL_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_PISTOL;
|
|
case PICKUP_VEHICLE_WEAPON_COMBATPISTOL_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_COMBATPISTOL;
|
|
case PICKUP_VEHICLE_WEAPON_PISTOL50_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_PISTOL50;
|
|
case PICKUP_VEHICLE_WEAPON_APPISTOL_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_APPISTOL;
|
|
case PICKUP_VEHICLE_WEAPON_MICROSMG_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_MICROSMG;
|
|
case PICKUP_VEHICLE_WEAPON_SMG_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_SMG;
|
|
case PICKUP_VEHICLE_WEAPON_SAWNOFF_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_SAWNOFF;
|
|
case PICKUP_VEHICLE_WEAPON_ASSAULTSMG_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_ASSAULTSMG;
|
|
case PICKUP_VEHICLE_WEAPON_GRENADE_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_GRENADE;
|
|
case PICKUP_VEHICLE_WEAPON_SMOKEGRENADE_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_SMOKEGRENADE;
|
|
case PICKUP_VEHICLE_WEAPON_STICKYBOMB_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_STICKYBOMB;
|
|
case PICKUP_VEHICLE_WEAPON_MOLOTOV_TYPE:
|
|
return PICKUP_VEHICLE_WEAPON_MOLOTOV;
|
|
|
|
case PICKUP_AMMO_BULLET_MP_TYPE:
|
|
return PICKUP_AMMO_BULLET_MP;
|
|
case PICKUP_AMMO_MISSILE_MP_TYPE:
|
|
return PICKUP_AMMO_MISSILE_MP;
|
|
|
|
case PICKUP_PORTABLE_CRATE_UNFIXED_TYPE:
|
|
return PICKUP_PORTABLE_CRATE_UNFIXED;
|
|
case PICKUP_VEHICLE_CUSTOM_SCRIPT_TYPE:
|
|
return PICKUP_VEHICLE_CUSTOM_SCRIPT;
|
|
case PICKUP_SUBMARINE_TYPE:
|
|
return PICKUP_SUBMARINE;
|
|
|
|
case PICKUP_WEAPON_CROWBAR_TYPE:
|
|
return PICKUP_WEAPON_CROWBAR;
|
|
case PICKUP_HEALTH_SNACK_TYPE:
|
|
return PICKUP_HEALTH_SNACK;
|
|
|
|
case PICKUP_PARACHUTE_TYPE:
|
|
return PICKUP_PARACHUTE;
|
|
default:
|
|
Assertf(0, "Unknown pickup type %d", PickupType);
|
|
}
|
|
}
|
|
return PickupType;
|
|
}
|
|
|
|
int CommandCreatePickup( int PickupHash, const scrVector & scrVecNewCoors, int PickupFlags, int amount, bool bScriptHostObject, int modelHashKey )
|
|
{
|
|
PickupHash = ConvertOldPickupTypeToHash(PickupHash);
|
|
|
|
Vector3 pickupPosition = Vector3(scrVecNewCoors);
|
|
Vector3 pickupOrientation = Vector3(1.0f, 1.0f, 1.0f);
|
|
|
|
#if __BANK
|
|
if (PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_DEBUG_CREATED)
|
|
{
|
|
Assertf(0, "Script pickup being created at %f, %f, %f as a debug pickup - bad flags set", pickupPosition.x, pickupPosition.y, pickupPosition.z);
|
|
PickupFlags &= ~CPickupPlacement::PLACEMENT_CREATION_FLAG_DEBUG_CREATED;
|
|
}
|
|
#endif
|
|
|
|
bool bMapPickup = PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_MAP;
|
|
|
|
// map pickups are only needed in MP as the flag dictates how the pickup is networked
|
|
if (!scriptVerifyf(!bMapPickup || NetworkInterface::IsGameInProgress(), "CREATE_PICKUP - PLACEMENT_FLAG_MAP set on a pickup in single player. This is only used in MP. Ignoring."))
|
|
{
|
|
PickupFlags &= ~CPickupPlacement::PLACEMENT_CREATION_FLAG_MAP;
|
|
bMapPickup = false;
|
|
}
|
|
|
|
// ignore the blip flags, they are not used anymore
|
|
scriptAssertf(PickupFlags < (1<<CPickupPlacement::PLACEMENT_FLAG_NUM_CREATION_FLAGS), "CREATE_PICKUP - invalid flags");
|
|
|
|
const CPickupData* pPickupData = CPickupDataManager::GetPickupData((u32)PickupHash);
|
|
|
|
if (scriptVerifyf(pPickupData, "CREATE_PICKUP - invalid pickup type"))
|
|
{
|
|
#if !__NO_OUTPUT
|
|
const CBaseModelInfo* pModelInfo = NULL;
|
|
#endif
|
|
u32 customModelIndex = fwModelId::MI_INVALID;
|
|
|
|
if (modelHashKey != 0 && CTheScripts::Frack2())
|
|
{
|
|
fwModelId modelId;
|
|
#if !__NO_OUTPUT
|
|
pModelInfo =
|
|
#endif
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) modelHashKey, &modelId);
|
|
|
|
if (scriptVerifyf(modelId.IsValid(), "%s: CREATE_PICKUP - the custom model is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter()) &&
|
|
scriptVerifyf(CModelInfo::HaveAssetsLoaded(modelId), "%s: CREATE_PICKUP - the custom model is not loaded", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
customModelIndex = modelId.GetModelIndex();
|
|
}
|
|
}
|
|
|
|
if (bScriptHostObject && !bMapPickup && (CTheScripts::GetCurrentGtaScriptHandlerNetwork() && CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()))
|
|
{
|
|
if (!SCRIPT_VERIFY (CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()->IsHostLocal(), "CREATE_PICKUP - Non-host machines cannot create host pickups"))
|
|
{
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
}
|
|
}
|
|
|
|
CPickupPlacement* pPlacement = CPickupManager::RegisterPickupPlacement((u32)PickupHash, pickupPosition, pickupOrientation, (PlacementFlags)PickupFlags, NULL, customModelIndex);
|
|
|
|
if (pPlacement)
|
|
{
|
|
#if !__NO_OUTPUT
|
|
scriptDebugf1("%s: CREATE_PICKUP 0x%p, PickupHash %d, overridden model %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pPlacement, PickupHash, pModelInfo ? pModelInfo->GetModelName() : "null");
|
|
#endif
|
|
|
|
if (CTheScripts::GetCurrentGtaScriptHandler()->RegisterNewScriptObject(static_cast<scriptHandlerObject&>(*pPlacement), bScriptHostObject, !bMapPickup))
|
|
{
|
|
if (amount >= 0)
|
|
{
|
|
pPlacement->SetAmount(static_cast<u16>(amount));
|
|
}
|
|
|
|
if (scriptVerify(pPlacement->GetScriptInfo()))
|
|
{
|
|
return pPlacement->GetScriptInfo()->GetObjectId();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CPickupManager::RemovePickupPlacement(pPlacement);
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
}
|
|
|
|
void CommandSetCustomPickupWeaponHash(int weaponHash, int pickupPlacementIndex)
|
|
{
|
|
CPickupPlacement* pPickupPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(pickupPlacementIndex));
|
|
|
|
if (pPickupPlacement)
|
|
{
|
|
pPickupPlacement->SetWeaponHash(weaponHash);
|
|
}
|
|
}
|
|
|
|
void CommandForcePickupRotateFaceUp()
|
|
{
|
|
CPickupManager::SetForceRotatePickupFaceUp();
|
|
}
|
|
|
|
int CommandCreatePickupRotate( int PickupHash, const scrVector & scrVecCoors, const scrVector & scrVecOrientation, int PickupFlags, int amount, s32 RotOrder, bool bScriptHostObject, int modelHashKey )
|
|
{
|
|
PickupHash = ConvertOldPickupTypeToHash(PickupHash);
|
|
|
|
scriptAssertf(PickupFlags < (1<<CPickupPlacement::PLACEMENT_FLAG_NUM_CREATION_FLAGS), "CREATE_PICKUP_ROTATE - invalid flags");
|
|
|
|
const CPickupData* pPickupData = CPickupDataManager::GetPickupData((u32)PickupHash);
|
|
|
|
if (scriptVerifyf(pPickupData, "CREATE_PICKUP_ROTATE - invalid pickup type"))
|
|
{
|
|
Vector3 pickupPosition = Vector3(scrVecCoors);
|
|
Vector3 pickupOrientation = Vector3(scrVecOrientation);
|
|
pickupOrientation *= DtoR; // Convert the Orientation vector to Radians
|
|
|
|
#if __BANK
|
|
if (PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_DEBUG_CREATED)
|
|
{
|
|
Assertf(0, "Script pickup being created at %f, %f, %f as a debug pickup - bad flags set", pickupPosition.x, pickupPosition.y, pickupPosition.z);
|
|
PickupFlags &= ~CPickupPlacement::PLACEMENT_CREATION_FLAG_DEBUG_CREATED;
|
|
}
|
|
#endif
|
|
bool bMapPickup = PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_MAP;
|
|
|
|
// map pickups are only needed in MP as the flag dictates how the pickup is networked
|
|
if (!scriptVerifyf(!bMapPickup || NetworkInterface::IsGameInProgress(), "CREATE_PICKUP_ROTATE - PLACEMENT_FLAG_MAP set on a pickup in single player. This is only used in MP. Ignoring."))
|
|
{
|
|
PickupFlags &= ~CPickupPlacement::PLACEMENT_CREATION_FLAG_MAP;
|
|
bMapPickup = false;
|
|
}
|
|
|
|
// Convert the order of Euler rotations from whatever was passed in to XYZ so that the rest of the pickup code can work the same as it always did
|
|
Quaternion quatRotation;
|
|
CScriptEulers::QuaternionFromEulers(quatRotation, pickupOrientation, static_cast<EulerAngleOrder>(RotOrder));
|
|
pickupOrientation = CScriptEulers::QuaternionToEulers(quatRotation, EULER_XYZ);
|
|
|
|
u32 customModelIndex = fwModelId::MI_INVALID;
|
|
|
|
#if !__NO_OUTPUT
|
|
const CBaseModelInfo* pModelInfo = NULL;
|
|
#endif
|
|
if (CTheScripts::Frack() && modelHashKey != 0)
|
|
{
|
|
fwModelId modelId;
|
|
|
|
#if !__NO_OUTPUT
|
|
pModelInfo =
|
|
#endif
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) modelHashKey, &modelId);
|
|
|
|
if (scriptVerifyf(modelId.IsValid(), "%s: CREATE_PICKUP_ROTATE - the custom model is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter()) &&
|
|
scriptVerifyf(CModelInfo::HaveAssetsLoaded(modelId), "%s: CREATE_PICKUP_ROTATE - the custom model is not loaded", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
customModelIndex = modelId.GetModelIndex();
|
|
}
|
|
}
|
|
|
|
if (bScriptHostObject && !bMapPickup && (CTheScripts::GetCurrentGtaScriptHandlerNetwork() && CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()))
|
|
{
|
|
if (!SCRIPT_VERIFY (CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()->IsHostLocal(), "CREATE_PICKUP_ROTATE - Non-host machines cannot create host pickups"))
|
|
{
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
}
|
|
}
|
|
|
|
CPickupPlacement* pPlacement = CPickupManager::RegisterPickupPlacement((u32)PickupHash, pickupPosition, pickupOrientation, (PlacementFlags)PickupFlags, NULL, customModelIndex);
|
|
|
|
if (pPlacement && CTheScripts::Frack2())
|
|
{
|
|
#if !__NO_OUTPUT
|
|
scriptDebugf1("%s: CREATE_PICKUP_ROTATE 0x%p, PickupHash %d, overridden model %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pPlacement, PickupHash, pModelInfo ? pModelInfo->GetModelName() : "null");
|
|
#endif
|
|
|
|
if (CTheScripts::GetCurrentGtaScriptHandler()->RegisterNewScriptObject(static_cast<scriptHandlerObject&>(*pPlacement), bScriptHostObject, !bMapPickup))
|
|
{
|
|
if (amount >= 0)
|
|
{
|
|
pPlacement->SetAmount(static_cast<u16>(amount));
|
|
}
|
|
|
|
if (scriptVerify(pPlacement->GetScriptInfo()))
|
|
{
|
|
return pPlacement->GetScriptInfo()->GetObjectId();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CPickupManager::RemovePickupPlacement(pPlacement);
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
}
|
|
|
|
void CommandBlockPlayersForPickup(int /*pickupID*/, int /*playerFlags*/)
|
|
{
|
|
/*
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
scriptHandlerObject* pObject = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(pickupID);
|
|
|
|
if (scriptVerifyf(pObject, "BLOCK_PLAYERS_FOR_PICKUP - Pickup does not exist"))
|
|
{
|
|
if (scriptVerifyf(static_cast<CGameScriptHandlerObject*>(pObject)->GetType() == SCRIPT_HANDLER_OBJECT_TYPE_PICKUP, "BLOCK_PLAYERS_FOR_PICKUP - This is not a pickup id"))
|
|
{
|
|
CPickupPlacement* pPlacement = SafeCast(CPickupPlacement, pObject);
|
|
|
|
if(scriptVerifyf(pPlacement->GetIsMapPlacement(), "BLOCK_PLAYERS_FOR_PICKUP - This is currently only supported for map pickups (using PLACEMENT_FLAG_MAP)"))
|
|
{
|
|
scriptAssertf(0, "BLOCK_PLAYERS_FOR_PICKUP is deprecated");
|
|
//pPlacement->SetPlayersAvailability(playerFlags);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
scriptAssertf(0, "BLOCK_PLAYERS_FOR_PICKUP is deprecated");
|
|
}
|
|
|
|
void CommandBlockPlayersForAmbientPickup(int pickupIndex, int playerFlag)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(pickupIndex);
|
|
|
|
if(pPickup)
|
|
{
|
|
if(pPickup->GetNetworkObject())
|
|
{
|
|
#if __BANK
|
|
if(NetworkUtils::IsNetworkCloneOrMigrating(pPickup))
|
|
{
|
|
scriptAssertf(false, "This function can only be called on players who own the pickup. Pickup index:%d", pickupIndex);
|
|
return;
|
|
}
|
|
#endif
|
|
static_cast<CNetObjPickup*>(pPickup->GetNetworkObject())->SetBlockedPlayersFromCollecting(playerFlag);
|
|
}
|
|
else
|
|
{
|
|
scriptAssertf(false, "Can't block players of pickup that has no network object. Pickup index:%d", pickupIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
scriptAssertf(false, "Can't block players of pickup that doesn't exist. Pickup index:%d", pickupIndex);
|
|
}
|
|
}
|
|
|
|
int CreateAmbientPickup( int PickupHash, const scrVector & scrVecNewCoors, int PickupFlags, int amount, int modelHashKey, bool bCreateAsScriptObject, bool bScriptHostObject, bool bNetworked )
|
|
{
|
|
PickupHash = ConvertOldPickupTypeToHash(PickupHash);
|
|
|
|
int iPickupIndex = NULL_IN_SCRIPTING_LANGUAGE;
|
|
|
|
scriptAssertf(PickupFlags < (1<<CPickupPlacement::PLACEMENT_FLAG_NUM_CREATION_FLAGS), "CREATE_AMBIENT_PICKUP - invalid flags");
|
|
|
|
const CPickupData* pPickupData = CPickupDataManager::GetPickupData((u32)PickupHash);
|
|
|
|
if (bCreateAsScriptObject && bScriptHostObject && (CTheScripts::GetCurrentGtaScriptHandlerNetwork() && CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()))
|
|
{
|
|
if (!SCRIPT_VERIFY (CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()->IsHostLocal(), "CREATE_AMBIENT_PICKUP - Non-host machines cannot create host pickups"))
|
|
{
|
|
return iPickupIndex;
|
|
}
|
|
}
|
|
|
|
if (scriptVerifyf(pPickupData, "CREATE_AMBIENT_PICKUP - invalid pickup type"))
|
|
{
|
|
strLocalIndex customModelIndex = strLocalIndex(fwModelId::MI_INVALID);
|
|
|
|
if (modelHashKey != 0)
|
|
{
|
|
fwModelId modelId;
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) modelHashKey, &modelId);
|
|
|
|
if (scriptVerifyf(modelId.IsValid(), "%s: CREATE_AMBIENT_PICKUP - the custom model is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter()) &&
|
|
scriptVerifyf(CModelInfo::HaveAssetsLoaded(modelId), "%s: CREATE_AMBIENT_PICKUP - the custom model is not loaded", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
customModelIndex = modelId.GetModelIndex();
|
|
}
|
|
}
|
|
|
|
Matrix34 placementM;
|
|
placementM.Identity();
|
|
placementM.d = Vector3(scrVecNewCoors);
|
|
|
|
CPickup* pPickup = CPickupManager::CreatePickup((u32)PickupHash, placementM, NULL, bNetworked, customModelIndex.Get(), true, bCreateAsScriptObject);
|
|
|
|
if (pPickup)
|
|
{
|
|
// Should we attempt to snap this to the ground?
|
|
if( (PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_SNAP_TO_GROUND) != 0 )
|
|
{
|
|
bool bOrientToGround = (PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_ORIENT_TO_GROUND) !=0;
|
|
bool bUpright = (PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_UPRIGHT) !=0;
|
|
|
|
pPickup->SetPlaceOnGround(bOrientToGround,bUpright);
|
|
}
|
|
|
|
if (amount >= 0)
|
|
{
|
|
pPickup->SetAmount(amount);
|
|
}
|
|
|
|
if (bCreateAsScriptObject)
|
|
{
|
|
CTheScripts::RegisterEntity(pPickup, bScriptHostObject, bNetworked);
|
|
}
|
|
|
|
pPickup->SetDontFadeOut();
|
|
|
|
if( (PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_PLAYER_GIFT) != 0 )
|
|
{
|
|
pPickup->SetPlayerGift();
|
|
}
|
|
|
|
if( (PickupFlags & CPickupPlacement::PLACEMENT_CREATION_FLAG_ON_OBJECT) != 0 )
|
|
{
|
|
pPickup->SetLyingOnFixedObject();
|
|
}
|
|
|
|
iPickupIndex = CTheScripts::GetGUIDFromEntity(*pPickup);
|
|
}
|
|
}
|
|
|
|
return iPickupIndex;
|
|
}
|
|
|
|
int CommandCreateAmbientPickup( int pickupHash, const scrVector & scrVecNewCoors, int PickupFlags, int amount, int modelHashKey, bool bCreateAsScriptObject, bool bScriptHostObject)
|
|
{
|
|
bool networked = true;
|
|
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
//@@: range COMMANDCREATEAMBIENTPICKUP {
|
|
// we want to send telemetry to detect cheater who spawn cash
|
|
if(CPickupManager::PickupHashIsMoneyType(pickupHash))
|
|
{
|
|
networked = CPickupManager::IsNetworkedMoneyPickupAllowed();
|
|
u64 id = 0;
|
|
rlCreateUUID(&id);
|
|
|
|
//Should we append cash created metric locally.
|
|
bool appendCashCreated = true;
|
|
//@@: location COMMANDCREATEAMBIENTPICKUP_CASH_CREATED
|
|
const unsigned numRemotePhysicalPlayers = netInterface::GetNumRemotePhysicalPlayers();
|
|
if (numRemotePhysicalPlayers > 0)
|
|
{
|
|
//Random my ass. ;)
|
|
const int index = fwRandom::GetRandomNumberInRange(0, (int)numRemotePhysicalPlayers);
|
|
|
|
const netPlayer* const* remotePhysicalPlayers = netInterface::GetRemotePhysicalPlayers();
|
|
const netPlayer* pPlayer = remotePhysicalPlayers[index];
|
|
if (pPlayer)
|
|
{
|
|
//Don't send locally since a peer is already sending it for us.
|
|
appendCashCreated = false;
|
|
|
|
// Send an event to the other peers so they also send the metric
|
|
CReportCashSpawnEvent::Trigger(id, amount, pickupHash, pPlayer->GetActivePlayerIndex());
|
|
}
|
|
}
|
|
|
|
//We didn't manage to send the request to any peer, so try locally.
|
|
if (appendCashCreated)
|
|
{
|
|
CNetworkTelemetry::AppendCashCreated(id, NetworkInterface::GetLocalGamerHandle(), amount, pickupHash);
|
|
}
|
|
}
|
|
//@@: } COMMANDCREATEAMBIENTPICKUP
|
|
}
|
|
|
|
return CreateAmbientPickup( pickupHash, scrVecNewCoors, PickupFlags, amount, modelHashKey, bCreateAsScriptObject, bScriptHostObject, networked);
|
|
|
|
}
|
|
|
|
int CommandCreateNonNetworkedAmbientPickup( int PickupHash, const scrVector & scrVecNewCoors, int PickupFlags, int amount, int modelHashKey, bool bCreateAsScriptObject, bool bScriptHostObject)
|
|
{
|
|
return CreateAmbientPickup( PickupHash, scrVecNewCoors, PickupFlags, amount, modelHashKey, bCreateAsScriptObject, bScriptHostObject, false );
|
|
}
|
|
|
|
int CreatePortablePickup( int PickupHash, const scrVector & scrVecNewCoors, bool SnapToGround, int modelHashKey, bool bNetworked )
|
|
{
|
|
PickupHash = ConvertOldPickupTypeToHash(PickupHash);
|
|
|
|
int iPickupIndex = NULL_IN_SCRIPTING_LANGUAGE;
|
|
|
|
const CPickupData* pPickupData = CPickupDataManager::GetPickupData((u32)PickupHash);
|
|
|
|
if (scriptVerifyf(pPickupData, "CREATE_PORTABLE_PICKUP - invalid pickup type") &&
|
|
scriptVerifyf(pPickupData->GetInvisibleWhenCarried(), "CREATE_PORTABLE_PICKUP - this pickup type is not portable"))
|
|
{
|
|
if (CTheScripts::GetCurrentGtaScriptHandlerNetwork() && CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent())
|
|
{
|
|
if (!SCRIPT_VERIFY (CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()->IsHostLocal(), "CREATE_PORTABLE_PICKUP - Non-host machines cannot create host pickups"))
|
|
{
|
|
#if __BANK
|
|
if(NetworkInterface::IsGameInProgress() && PARAM_netDebugCreatePortablePickup.Get())
|
|
{
|
|
Displayf("CreatePortablePickup SUCCESS iPickupIndex %d. PickupHash 0x%x, scrVecNewCoors %.2f, %.2f, %.2f, SnapToGround %s, modelHashKey 0x%x, bNetworked %s. Frame: %d",
|
|
iPickupIndex,PickupHash,scrVecNewCoors.x,scrVecNewCoors.y,scrVecNewCoors.z, SnapToGround?"TRUE":"FALSE", modelHashKey, bNetworked?"TRUE":"FALSE",fwTimer::GetFrameCount() );
|
|
}
|
|
#endif
|
|
|
|
return iPickupIndex;
|
|
}
|
|
}
|
|
|
|
if (scriptVerifyf(pPickupData->GetAttachmentBone() != BONETAG_INVALID, "CREATE_PORTABLE_PICKUP - this pickup type is not setup as a portable pickup in pickups.meta"))
|
|
{
|
|
strLocalIndex customModelIndex = strLocalIndex(fwModelId::MI_INVALID);
|
|
|
|
if (modelHashKey != 0)
|
|
{
|
|
fwModelId modelId;
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) modelHashKey, &modelId);
|
|
|
|
if (scriptVerifyf(modelId.IsValid(), "%s: CREATE_PORTABLE_PICKUP - the custom model is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter()) &&
|
|
scriptVerifyf(CModelInfo::HaveAssetsLoaded(modelId), "%s: CREATE_PORTABLE_PICKUP - the custom model is not loaded", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
customModelIndex = modelId.GetModelIndex();
|
|
}
|
|
}
|
|
|
|
Matrix34 placementM;
|
|
placementM.Identity();
|
|
placementM.d = Vector3(scrVecNewCoors);
|
|
|
|
CPickup* pPickup = CPickupManager::CreatePickup((u32)PickupHash, placementM, NULL, bNetworked, customModelIndex.Get(), true, true);
|
|
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetPortable();
|
|
pPickup->GetLodData().SetResetDisabled(true);
|
|
CTheScripts::RegisterEntity(pPickup, bNetworked, bNetworked);
|
|
|
|
if (SnapToGround)
|
|
{
|
|
pPickup->SetPlaceOnGround(true, true);
|
|
}
|
|
|
|
iPickupIndex = CTheScripts::GetGUIDFromEntity(*pPickup);
|
|
}
|
|
}
|
|
}
|
|
|
|
#if __BANK
|
|
if(NetworkInterface::IsGameInProgress() && PARAM_netDebugCreatePortablePickup.Get())
|
|
{
|
|
Displayf("CreatePortablePickup return iPickupIndex %d. PickupHash 0x%x, scrVecNewCoors %.2f, %.2f, %.2f, SnapToGround %s, modelHashKey 0x%x, bNetworked %s. Frame: %d",
|
|
iPickupIndex,PickupHash,scrVecNewCoors.x,scrVecNewCoors.y,scrVecNewCoors.z, SnapToGround?"TRUE":"FALSE", modelHashKey, bNetworked?"TRUE":"FALSE",fwTimer::GetFrameCount() );
|
|
}
|
|
#endif
|
|
return iPickupIndex;
|
|
}
|
|
|
|
int CommandCreatePortablePickup( int PickupHash, const scrVector & scrVecNewCoors, bool SnapToGround, int modelHashKey )
|
|
{
|
|
return CreatePortablePickup( PickupHash, scrVecNewCoors, SnapToGround, modelHashKey, true );
|
|
}
|
|
|
|
int CommandCreateNonNetworkedPortablePickup( int PickupHash, const scrVector & scrVecNewCoors, bool SnapToGround, int modelHashKey )
|
|
{
|
|
return CreatePortablePickup( PickupHash, scrVecNewCoors, SnapToGround, modelHashKey, false );
|
|
}
|
|
|
|
void CommandAttachPortablePickupToPed(int pickupID, int pedID)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(pickupID);
|
|
CPed* pPed = CTheScripts::GetEntityToModifyFromGUID<CPed>(pedID);
|
|
|
|
if (pPickup && pPed)
|
|
{
|
|
// avoid asserts if this command has been called twice and the pickup is still trying to attach itself to the ped
|
|
if (pPickup->GetPendingCarrier() == pPed )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (scriptVerifyf(pPickup->IsFlagSet(CPickup::PF_Portable), "ATTACH_PORTABLE_PICKUP_TO_PED - the pickup is not portable") &&
|
|
scriptVerifyf(!pPickup->GetIsAttached(), "ATTACH_PORTABLE_PICKUP_TO_PED - the pickup is already attached") &&
|
|
scriptVerifyf(!pPed->GetPlayerInfo() || !pPed->GetPlayerInfo()->PortablePickupPending, "ATTACH_PORTABLE_PICKUP_TO_PED - there is another pickup pending attachement to this ped"))
|
|
{
|
|
pPickup->AttachPortablePickupToPed(pPed, "ATTACH_PORTABLE_PICKUP_TO_PED script command");
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandDetachPortablePickupFromPed(int pickupID)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(pickupID);
|
|
|
|
if (pPickup)
|
|
{
|
|
if (scriptVerifyf(pPickup->IsFlagSet(CPickup::PF_Portable), "DETACH_PORTABLE_PICKUP_FROM_PED - the pickup is not portable") &&
|
|
scriptVerifyf(pPickup->GetIsAttached(), "DETACH_PORTABLE_PICKUP_FROM_PED - the pickup is not attached") &&
|
|
scriptVerifyf(static_cast<CEntity*>(pPickup->GetAttachParent())->GetIsTypePed(), "DETACH_PORTABLE_PICKUP_FROM_PED - the pickup is not attached to a ped"))
|
|
{
|
|
pPickup->DetachPortablePickupFromPed("DETACH_PORTABLE_PICKUP_FROM_PED");
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandForcePortablePickupLastAccessiblePositionSetting(int pickupID)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(pickupID);
|
|
if (pPickup)
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "PORTABLE_PICKUP_FORCE_LAST_ACCESSIBLE_POSITION", "%s", pPickup->GetLogName());
|
|
log.WriteDataValue("Position", "x:%.2f, y:%.2f, z:%.2f", pPickup->GetTransform().GetPosition().GetXf(), pPickup->GetTransform().GetPosition().GetYf(), pPickup->GetTransform().GetPosition().GetZf());
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
}
|
|
#endif
|
|
pPickup->ForceSetLastAccessibleLocation();
|
|
}
|
|
}
|
|
|
|
void CommandHidePortablePickupWhenDetached(int pickupID, bool bHide)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(pickupID);
|
|
|
|
if (pPickup)
|
|
{
|
|
if (scriptVerifyf(pPickup->IsFlagSet(CPickup::PF_Portable), "HIDE_PORTABLE_PICKUP_WHEN_DETACHED - the pickup is not portable"))
|
|
{
|
|
pPickup->SetHideWhenDetached(bHide);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetMaxNumPortablePickupsCarriedByPlayer(int modelHashKey, int max)
|
|
{
|
|
CPed * pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
|
|
if (scriptVerifyf(pPlayerPed, "SET_MAX_NUM_PORTABLE_PICKUPS_CARRIED_BY_PLAYER - local player does not exist") &&
|
|
scriptVerifyf(max >= -1, "SET_MAX_NUM_PORTABLE_PICKUPS_CARRIED_BY_PLAYER - max is invalid (%d)", max) &&
|
|
AssertVerify(pPlayerPed->GetPlayerInfo()))
|
|
{
|
|
if (modelHashKey != 0)
|
|
{
|
|
fwModelId modelId;
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) modelHashKey, &modelId);
|
|
|
|
if (scriptVerifyf(modelId.IsValid(), "%s: SET_MAX_NUM_PORTABLE_PICKUPS_CARRIED_BY_PLAYER - the model is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
pPlayerPed->GetPlayerInfo()->SetMaxPortablePickupsOfTypePermitted(modelId.GetModelIndex(), max);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pPlayerPed->GetPlayerInfo()->m_maxPortablePickupsCarried = (s8)max;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetLocalPlayerCanCollectPortablePickups(bool bCanCollect)
|
|
{
|
|
CPed * pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
|
|
if (scriptVerifyf(pPlayerPed, "SET_LOCAL_PLAYER_CAN_COLLECT_PORTABLE_PICKUPS - local player does not exist") &&
|
|
AssertVerify(pPlayerPed->GetPlayerInfo()))
|
|
{
|
|
if (bCanCollect)
|
|
{
|
|
if (pPlayerPed->GetPlayerInfo()->m_maxPortablePickupsCarried == 0)
|
|
{
|
|
pPlayerPed->GetPlayerInfo()->m_maxPortablePickupsCarried = -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pPlayerPed->GetPlayerInfo()->m_maxPortablePickupsCarried = 0;
|
|
}
|
|
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "SET_LOCAL_PLAYER_CAN_COLLECT_PORTABLE_PICKUPS", "%s", bCanCollect ? "true" : "false");
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
bool CommandIsPickupRewardTypeSuppressed( s32 nPickupFlag )
|
|
{
|
|
return CPickupManager::IsSuppressionFlagSet( nPickupFlag );
|
|
}
|
|
|
|
void CommandSuppressPickupRewardType( s32 nPickupFlag, bool bClearPreviousFlags )
|
|
{
|
|
if( bClearPreviousFlags )
|
|
CPickupManager::ClearSuppressionFlags();
|
|
|
|
CPickupManager::SetSuppressionFlag( nPickupFlag );
|
|
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "SUPPRESS_PICKUP_REWARD", "%d", nPickupFlag);
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptName());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CommandClearAllPickupRewardTypeSuppression( void )
|
|
{
|
|
CPickupManager::ClearSuppressionFlags();
|
|
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "CLEAR_ALL_PICKUP_REWARD_SUPPRESSION", "");
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptName());
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void CommandClearPickupRewardTypeSuppression( s32 nPickupFlag )
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "CLEAR_PICKUP_REWARD_SUPPRESSION", "%d", nPickupFlag);
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptName());
|
|
}
|
|
#endif
|
|
|
|
return CPickupManager::ClearSuppressionFlag( nPickupFlag );
|
|
}
|
|
|
|
void CommandRenderFakePickup(const scrVector & pos, int glowType)
|
|
{
|
|
CPickupManager::RenderScriptedGlow(pos,glowType);
|
|
}
|
|
|
|
void CommandSetPickupObjectCollectableInVehicle(int pickupId)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(pickupId);
|
|
|
|
if (pPickup)
|
|
{
|
|
scriptAssertf(!pPickup->GetPlacement(), "SET_PICKUP_OBJECT_COLLECTABLE_IN_VEHICLE - the pickup object has been spawned by a pickup - use SET_PICKUP_COLLECTABLE_ON_MOUNT instead to avoid losing the this setting");
|
|
scriptAssertf(pPickup->GetPickupData()->GetCollectableOnFoot(), "SET_PICKUP_OBJECT_COLLECTABLE_IN_VEHICLE - this can only be called on pickups collectable on foot");
|
|
|
|
pPickup->SetAllowCollectionInVehicle();
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupTrackDamageEvents(int pickupId, bool set)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(pickupId);
|
|
|
|
if (pPickup)
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
netLoggingInterface *log = &NetworkInterface::GetObjectManager().GetLog();
|
|
if (log)
|
|
{
|
|
NetworkLogUtils::WriteLogEvent(*log, "SET_PICKUP_TRACK_DAMAGE_EVENTS", pPickup->GetLogName());
|
|
log->WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
log->WriteDataValue("Enable", "%s", set ? "TRUE" : "FALSE");
|
|
}
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
pPickup->SetForceWaitForFullySyncBeforeDestruction(set);
|
|
}
|
|
}
|
|
|
|
scrVector CommandGetPickupCoords( int iPickupID )
|
|
{
|
|
Vector3 coordVec(0.0,0.0,-100.0);
|
|
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"GET_PICKUP_COORDS - Pickup does not exist (or has been collected)" ))
|
|
{
|
|
coordVec = pPlacement->GetPickupPosition();
|
|
}
|
|
}
|
|
|
|
return coordVec;
|
|
}
|
|
|
|
void CommandSuppressPickupSoundForPickup( int iPickupID, bool suppress )
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(iPickupID);
|
|
|
|
if(pPickup)
|
|
{
|
|
pPickup->SetSuppressPickupAudio(suppress);
|
|
}
|
|
}
|
|
|
|
void CommandRemoveAllPickupsOfType(int iPickupHash)
|
|
{
|
|
iPickupHash = ConvertOldPickupTypeToHash(iPickupHash);
|
|
CPickupManager::RemoveAllPickupsOfType((u32)iPickupHash);
|
|
}
|
|
|
|
int CommandGetNumberOfPickupsOfType(int iPickupHash)
|
|
{
|
|
iPickupHash = ConvertOldPickupTypeToHash(iPickupHash);
|
|
return CPickupManager::CountPickupsOfType((u32)iPickupHash);
|
|
}
|
|
|
|
bool CommandHasPickupBeenCollected( int PickupID )
|
|
{
|
|
CGameScriptObjInfo objInfo(CGameScriptId(*CTheScripts::GetCurrentGtaScriptThread()), PickupID, 0);
|
|
|
|
return CPickupManager::HasPickupBeenCollected(objInfo);
|
|
}
|
|
|
|
void CommandRemovePickup( int PickupID )
|
|
{
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
scriptHandlerObject* pObject = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(PickupID);
|
|
|
|
if (scriptVerifyf(pObject, "REMOVE_PICKUP - Pickup does not exist"))
|
|
{
|
|
if (scriptVerifyf(static_cast<CGameScriptHandlerObject*>(pObject)->GetType() == SCRIPT_HANDLER_OBJECT_TYPE_PICKUP, "REMOVE_PICKUP - This is not a pickup id"))
|
|
{
|
|
CPickupPlacement* pPlacement = SafeCast(CPickupPlacement, pObject);
|
|
|
|
bool pickupIsLocal = !pPlacement->GetNetworkObject() || pPlacement->GetIsMapPlacement() || (!pPlacement->IsNetworkClone() && !pPlacement->GetNetworkObject()->IsPendingOwnerChange());
|
|
|
|
if (SCRIPT_VERIFY(pickupIsLocal, "REMOVE_PICKUP - Cannot remove a pickup controlled by another machine"))
|
|
{
|
|
CPickupManager::RemovePickupPlacement(pPlacement);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandCreateMoneyPickups( const scrVector & scrVecCoors, int amount, int numPickups, int modelHashKey)
|
|
{
|
|
Vector3 moneyPosition = Vector3(scrVecCoors);
|
|
|
|
SCRIPT_ASSERT(numPickups<=8, "CREATE_MONEY_PICKUPS - Can't create more than 8 money pickups" );
|
|
|
|
strLocalIndex customModelIndex = strLocalIndex(fwModelId::MI_INVALID);
|
|
|
|
if (modelHashKey != 0 && CTheScripts::Frack())
|
|
{
|
|
fwModelId modelId;
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) modelHashKey, &modelId);
|
|
|
|
if (scriptVerifyf(modelId.IsValid(), "%s: CREATE_MONEY_PICKUPS - the custom model is invalid", CTheScripts::GetCurrentScriptNameAndProgramCounter()) &&
|
|
scriptVerifyf(CModelInfo::HaveAssetsLoaded(modelId), "%s: CREATE_MONEY_PICKUPS - the custom model is not loaded", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
customModelIndex = modelId.GetModelIndex();
|
|
}
|
|
}
|
|
|
|
CPickupManager::CreateSomeMoney(moneyPosition, amount, numPickups, customModelIndex.Get());
|
|
}
|
|
|
|
void CommandSetPlayersDropMoneyInNetworkGame(bool /*bValue*/)
|
|
{
|
|
SCRIPT_ASSERT(false,"SET_PLAYERS_DROP_MONEY_IN_NETWORK_GAME - Needs reimplementation. Speak to John G or Phil" );
|
|
//CPickups::m_bPlayersDropMoneyInNetworkGame = bValue;
|
|
}
|
|
|
|
bool CommandRotateObject( int iObjectID, float fTargetRotation, float fRotationStep, bool bStopForCollisionFlag )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectID);
|
|
bool bResult = false;
|
|
|
|
if (pObj)
|
|
{
|
|
float fHeading;
|
|
float RotationDifference1, RotationDifference2;
|
|
bool ObjectHasCollided;
|
|
Matrix34 temp_mat;
|
|
Vector3 BBoxVMin, BBoxVMax;
|
|
Vector3 Point1, Point2, Point3, Point4;
|
|
|
|
fHeading = ( RtoD * pObj->GetTransform().GetHeading());
|
|
if (fHeading < 0.0f)
|
|
{
|
|
fHeading += 360.0f;
|
|
}
|
|
scriptAssertf(fRotationStep > 0.0f, "%s:ROTATE_OBJECT - Rotation Step must be greater than 0.0", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
if (fHeading == fTargetRotation)
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
else
|
|
{
|
|
RotationDifference1 = fTargetRotation - fHeading;
|
|
RotationDifference2 = fHeading - fTargetRotation;
|
|
if (RotationDifference1 < 0.0f)
|
|
{
|
|
RotationDifference1 += 360.0f;
|
|
}
|
|
if (RotationDifference2 < 0.0f)
|
|
{
|
|
RotationDifference2 += 360.0f;
|
|
}
|
|
if (RotationDifference1 < RotationDifference2)
|
|
{
|
|
if (RotationDifference1 < fRotationStep)
|
|
{
|
|
fHeading = fTargetRotation;
|
|
}
|
|
else
|
|
{
|
|
fHeading += fRotationStep;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (RotationDifference2 < fRotationStep)
|
|
{
|
|
fHeading = fTargetRotation;
|
|
}
|
|
else
|
|
{
|
|
fHeading -= fRotationStep;
|
|
}
|
|
}
|
|
ObjectHasCollided = FALSE;
|
|
if (bStopForCollisionFlag)
|
|
{
|
|
Vector3 TempCoors = VEC3V_TO_VECTOR3(pObj->GetTransform().GetPosition());
|
|
temp_mat.Identity();
|
|
temp_mat.RotateLocalZ(( DtoR * fHeading));
|
|
temp_mat.Translate(TempCoors);
|
|
BBoxVMin = pObj->GetBaseModelInfo()->GetBoundingBoxMin();
|
|
BBoxVMax = pObj->GetBaseModelInfo()->GetBoundingBoxMax();
|
|
Point1 = Vector3(BBoxVMin.x, BBoxVMin.y, BBoxVMin.z);
|
|
Point2 = Vector3(BBoxVMax.x, BBoxVMin.y, BBoxVMax.z);
|
|
Point3 = Vector3(BBoxVMax.x, BBoxVMax.y, BBoxVMin.z);
|
|
Point4 = Vector3(BBoxVMin.x, BBoxVMax.y, BBoxVMax.z);
|
|
Point1 = temp_mat * Point1;
|
|
Point2 = temp_mat * Point2;
|
|
Point3 = temp_mat * Point3;
|
|
Point4 = temp_mat * Point4;
|
|
}
|
|
if (ObjectHasCollided)
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pObj->SetHeading(( DtoR * fHeading));
|
|
if (fHeading == fTargetRotation)
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return(bResult);
|
|
}
|
|
|
|
bool CommandSlideObject( int iObjectID, const scrVector & scrVecDestCoors, const scrVector & scrVecIncrement, bool bStopOnCollision )
|
|
{
|
|
Vector3 VecDestCoors = Vector3 (scrVecDestCoors);
|
|
Vector3 VecIncrement = Vector3 (scrVecIncrement);
|
|
|
|
bool bResult = false;
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectID);
|
|
|
|
if (pObj)
|
|
{
|
|
float XDiff, YDiff, ZDiff;
|
|
bool ObjectHasCollided;
|
|
Matrix34 temp_mat;
|
|
Vector3 BBoxVMin, BBoxVMax;
|
|
Vector3 Point1, Point2, Point3, Point4;
|
|
|
|
Vector3 TempCoors = VEC3V_TO_VECTOR3(pObj->GetTransform().GetPosition());
|
|
|
|
//if ((TempCoors.x == VecIncrement.x) && (TempCoors.y == VecIncrement.y) && (TempCoors.z == VecIncrement.z))
|
|
if (TempCoors == VecDestCoors)
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
else
|
|
{
|
|
XDiff = TempCoors.x - VecDestCoors.x;
|
|
YDiff = TempCoors.y - VecDestCoors.y;
|
|
ZDiff = TempCoors.z - VecDestCoors.z;
|
|
scriptAssertf(VecIncrement.x >= 0.0f, "%s:SLIDE_OBJECT - X Increment must be positive", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
scriptAssertf(VecIncrement.y >= 0.0f, "%s:SLIDE_OBJECT - Y Increment must be positive", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
scriptAssertf(VecIncrement.z >= 0.0f, "%s:SLIDE_OBJECT - Z Increment must be positive", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
if (XDiff >= 0.0f)
|
|
{
|
|
if (XDiff > VecIncrement.x)
|
|
{
|
|
TempCoors.x -= VecIncrement.x;
|
|
}
|
|
else
|
|
{
|
|
TempCoors.x = VecDestCoors.x;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XDiff = -XDiff;
|
|
if (XDiff > VecIncrement.x)
|
|
{
|
|
TempCoors.x += VecIncrement.x;
|
|
}
|
|
else
|
|
{
|
|
TempCoors.x = VecDestCoors.x;
|
|
}
|
|
}
|
|
if (YDiff >= 0.0f)
|
|
{
|
|
if (YDiff > VecIncrement.y)
|
|
{
|
|
TempCoors.y -= VecIncrement.y;
|
|
}
|
|
else
|
|
{
|
|
TempCoors.y = VecDestCoors.y;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
YDiff = -YDiff;
|
|
if (YDiff > VecIncrement.y)
|
|
{
|
|
TempCoors.y += VecIncrement.y;
|
|
}
|
|
else
|
|
{
|
|
TempCoors.y = VecDestCoors.y;
|
|
}
|
|
}
|
|
if (ZDiff >= 0.0f)
|
|
{
|
|
if (ZDiff > VecIncrement.z)
|
|
{
|
|
TempCoors.z -= VecIncrement.z;
|
|
}
|
|
else
|
|
{
|
|
TempCoors.z = VecDestCoors.z;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ZDiff = -ZDiff;
|
|
if (ZDiff > VecIncrement.z)
|
|
{
|
|
TempCoors.z += VecIncrement.z;
|
|
}
|
|
else
|
|
{
|
|
TempCoors.z = VecDestCoors.z;
|
|
}
|
|
}
|
|
ObjectHasCollided = FALSE;
|
|
if (bStopOnCollision)
|
|
{
|
|
temp_mat = MAT34V_TO_MATRIX34(pObj->GetMatrix());
|
|
temp_mat.d.SetX(TempCoors.x);
|
|
temp_mat.d.SetY(TempCoors.y);
|
|
temp_mat.d.SetZ(TempCoors.z);
|
|
BBoxVMin = pObj->GetBaseModelInfo()->GetBoundingBoxMin();
|
|
BBoxVMax = pObj->GetBaseModelInfo()->GetBoundingBoxMax();
|
|
Point1 = Vector3(BBoxVMin.x, BBoxVMin.y, BBoxVMin.z);
|
|
Point2 = Vector3(BBoxVMax.x, BBoxVMin.y, BBoxVMax.z);
|
|
Point3 = Vector3(BBoxVMax.x, BBoxVMax.y, BBoxVMin.z);
|
|
Point4 = Vector3(BBoxVMin.x, BBoxVMax.y, BBoxVMax.z);
|
|
Point1 = temp_mat * Point1;
|
|
Point2 = temp_mat * Point2;
|
|
Point3 = temp_mat * Point3;
|
|
Point4 = temp_mat * Point4;
|
|
|
|
}
|
|
if (ObjectHasCollided)
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
else
|
|
{
|
|
pObj->Teleport(TempCoors);
|
|
if ((TempCoors.x == VecDestCoors.x) && (TempCoors.y == VecDestCoors.y) && (TempCoors.z == VecDestCoors.z))
|
|
{
|
|
bResult = TRUE;
|
|
}
|
|
else
|
|
{
|
|
bResult = FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(bResult);
|
|
}
|
|
|
|
void CommandSetObjectTargettable( int iObjectID, bool bTargettable )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectID);
|
|
|
|
if (pObj)
|
|
{
|
|
CPed * pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
if (bTargettable)
|
|
{
|
|
pObj->SetObjectTargettable(true);
|
|
}
|
|
else
|
|
{
|
|
pObj->SetObjectTargettable(false);
|
|
CPlayerPedTargeting & targeting = pPlayerPed->GetPlayerInfo()->GetTargeting();
|
|
if (pObj == targeting.GetLockOnTarget() )
|
|
{
|
|
targeting.SetLockOnTarget(NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectForceVehiclesToAvoid(int iObjectID, bool bAvoid )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectID);
|
|
|
|
if (pObj)
|
|
{
|
|
pObj->SetForceVehiclesToAvoid(bAvoid);
|
|
}
|
|
}
|
|
|
|
s32 CommandGetClosestObjectOfType(const scrVector & scrVecCentreCoors, float Radius, int ObjectModelHashKey, bool bRegisterAsScriptObject, bool bScriptHostObject, bool bRegisterAsNetworkObject)
|
|
{
|
|
s32 ReturnObjectIndex = NULL_IN_SCRIPTING_LANGUAGE;
|
|
|
|
Vector3 VecNewCoors = Vector3(scrVecCentreCoors);
|
|
|
|
// non-networked objects should always be treated as client objects
|
|
if (bRegisterAsScriptObject && bScriptHostObject)
|
|
{
|
|
if (!bRegisterAsNetworkObject)
|
|
{
|
|
scriptAssertf(0, "GET_CLOSEST_OBJECT_OF_TYPE - Script host objects must be networked. Forcing this to true");
|
|
bRegisterAsNetworkObject = true;
|
|
}
|
|
|
|
if (CTheScripts::GetCurrentGtaScriptHandlerNetwork() && CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent())
|
|
{
|
|
if (!SCRIPT_VERIFY (CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()->IsHostLocal(), "GET_CLOSEST_OBJECT_OF_TYPE - Non-host machines cannot create host objects"))
|
|
{
|
|
return ReturnObjectIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
// B*1982595 & 2111681 & 2116196: Tell the closest object lookup to only consider objects with the specific "ownedby" status that we are looking for (See switch statement below).
|
|
// This prevents the command from picking up frag objects and the like and allows it to find an actually useful object if one exists in the search range.
|
|
s32 nOwnedByFlags = 0xFFFFFFFF;
|
|
if(bRegisterAsScriptObject)
|
|
{
|
|
nOwnedByFlags = ENTITY_OWNEDBY_MASK_RANDOM | ENTITY_OWNEDBY_MASK_TEMP | ENTITY_OWNEDBY_MASK_SCRIPT;
|
|
}
|
|
|
|
CEntity *pClosestEntity = CObject::GetPointerToClosestMapObjectForScript(VecNewCoors.x, VecNewCoors.y, VecNewCoors.z, Radius, ObjectModelHashKey, ENTITY_TYPE_MASK_BUILDING | ENTITY_TYPE_MASK_OBJECT | ENTITY_TYPE_MASK_DUMMY_OBJECT, nOwnedByFlags);
|
|
if (pClosestEntity)
|
|
{
|
|
CObject *pClosestObject = NULL;
|
|
|
|
if (pClosestEntity->GetIsTypeDummyObject())
|
|
{
|
|
CDummyObject *pDummyObject = static_cast<CDummyObject*>(pClosestEntity);
|
|
pClosestObject = CObjectPopulation::ConvertToRealObject(pDummyObject);
|
|
|
|
scriptAssertf(pClosestObject, "%s:GET_CLOSEST_OBJECT_OF_TYPE - Failed to convert dummy object %s to a real object",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName());
|
|
}
|
|
else if (pClosestEntity->GetIsTypeObject())
|
|
{
|
|
pClosestObject = static_cast<CObject*>(pClosestEntity);
|
|
|
|
if (pClosestObject->IsADoor() && (bRegisterAsScriptObject||bRegisterAsNetworkObject) && NetworkInterface::IsGameInProgress())
|
|
{
|
|
scriptAssertf(0, "%s:GET_CLOSEST_OBJECT_OF_TYPE - you can't call this on a door (%s) if you want to register as a script object or network it. Use the correct door commands.",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName());
|
|
return ReturnObjectIndex;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
scriptAssertf(0, "%s:GET_CLOSEST_OBJECT_OF_TYPE - closest entity %s is not an object or a dummy object",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName());
|
|
}
|
|
|
|
if (pClosestObject)
|
|
{
|
|
#if GTA_REPLAY
|
|
if(CReplayMgr::IsEditModeActive() == false)
|
|
{
|
|
CReplayMgr::RecordMapObject(pClosestObject);
|
|
}
|
|
#endif
|
|
if (bRegisterAsScriptObject && pClosestObject->IsNetworkClone())
|
|
{
|
|
scriptAssertf(0, "%s:GET_CLOSEST_OBJECT_OF_TYPE - can't register as a script object - the entity %s is not controlled by this machine (net id: %s)",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName(), pClosestObject->GetNetworkObject()->GetLogName());
|
|
bRegisterAsScriptObject = false;
|
|
}
|
|
|
|
if (bRegisterAsScriptObject)
|
|
{
|
|
// if this is a network game and we don't have an existing network object, register
|
|
if (bRegisterAsNetworkObject && NetworkInterface::IsGameInProgress() && !pClosestObject->GetNetworkObject())
|
|
{
|
|
NetworkInterface::RegisterObject(pClosestObject, 0, CNetObjGame::GLOBALFLAG_SCRIPTOBJECT, true);
|
|
|
|
if(pClosestObject && pClosestObject->GetNetworkObject())
|
|
{
|
|
CNetObjObject *pNetObjObject = SafeCast(CNetObjObject, pClosestObject->GetNetworkObject());
|
|
pNetObjObject->SetScriptGrabParameters(VecNewCoors, Radius);
|
|
}
|
|
}
|
|
|
|
CDummyObject *pRelatedDummy = NULL;
|
|
fwInteriorLocation RelatedDummyLocation;
|
|
s32 IplIndexOfObject = 0;
|
|
|
|
switch (pClosestObject->GetOwnedBy())
|
|
{
|
|
case ENTITY_OWNEDBY_RANDOM :
|
|
{
|
|
pRelatedDummy = pClosestObject->GetRelatedDummy();
|
|
RelatedDummyLocation = pClosestObject->GetRelatedDummyLocation();
|
|
IplIndexOfObject = pClosestObject->GetIplIndex();
|
|
|
|
CTheScripts::RegisterEntity(pClosestObject, bScriptHostObject, bRegisterAsNetworkObject);
|
|
scriptAssertf(pClosestObject->GetRelatedDummy() == NULL, "%s:GET_CLOSEST_OBJECT_OF_TYPE - expected CObject::SetupMissionState() to have called ClearRelatedDummy() for %s",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName());
|
|
|
|
pClosestObject->SetIplIndex(0);
|
|
}
|
|
break;
|
|
|
|
case ENTITY_OWNEDBY_TEMP :
|
|
// If an object has been grabbed then marked as no longer needed, it will be a Temp object
|
|
// Until Changelist 2412021, it would have been ENTITY_OWNEDBY_RANDOM
|
|
scriptAssertf(0, "%s:GET_CLOSEST_OBJECT_OF_TYPE - GetOwnedBy() returned ENTITY_OWNEDBY_TEMP for the entity with model %s so it's not safe to return to script. Maybe this entity had already been grabbed once from the world and later set as no longer needed",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName());
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
// break;
|
|
|
|
case ENTITY_OWNEDBY_SCRIPT :
|
|
{ // If this is already a mission object
|
|
const GtaThread* pCreationThread = pClosestObject->GetThreadThatCreatedMe();
|
|
if (scriptVerifyf(pCreationThread, "%s:GET_CLOSEST_OBJECT_OF_TYPE - creation thread not found (object's model is %s)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName()) )
|
|
{
|
|
if (pCreationThread==CTheScripts::GetCurrentGtaScriptThread())
|
|
{ // If the mission object was grabbed/created by this script, return its ID here
|
|
// Don't run all the model swap code
|
|
scriptAssertf(0, "%s:GET_CLOSEST_OBJECT_OF_TYPE - entity with model %s is already a mission object owned by this script",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName());
|
|
|
|
return CTheScripts::GetGUIDFromEntity(*pClosestObject);
|
|
}
|
|
else
|
|
{ // If the mission object was grabbed/created by another script then assert and return NULL
|
|
scriptAssertf(0, "%s:GET_CLOSEST_OBJECT_OF_TYPE - entity with model %s created by %s, trying to mark as mission entity by %s",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName(), const_cast<GtaThread*>(pCreationThread)->GetScriptName(), CTheScripts::GetCurrentScriptName());
|
|
}
|
|
}
|
|
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
}
|
|
break;
|
|
|
|
default :
|
|
scriptAssertf(0, "%s:GET_CLOSEST_OBJECT_OF_TYPE - Unexpected GetOwnedBy() value %d for entity with model %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestObject->GetOwnedBy(), pClosestEntity->GetModelName());
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
// break;
|
|
}
|
|
|
|
CScriptEntityExtension* pExtension = pClosestObject->GetExtension<CScriptEntityExtension>();
|
|
|
|
if (scriptVerifyf(pExtension, "%s:GET_CLOSEST_OBJECT_OF_TYPE - failed to get the script extension for the closest object with model %s", CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestEntity->GetModelName()))
|
|
{
|
|
pExtension->SetScriptObjectWasGrabbedFromTheWorld(true);
|
|
|
|
ReturnObjectIndex = CTheScripts::GetGUIDFromEntity(*pClosestObject);
|
|
|
|
spdSphere searchVolume((Vec3V) VecNewCoors, ScalarV(Radius));
|
|
CTheScripts::GetHiddenObjects().AddToHiddenObjectMap(ReturnObjectIndex, searchVolume, ObjectModelHashKey,
|
|
pRelatedDummy, RelatedDummyLocation, IplIndexOfObject);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ReturnObjectIndex = CTheScripts::GetGUIDFromEntity(*pClosestObject);
|
|
}
|
|
}
|
|
}
|
|
|
|
return ReturnObjectIndex;
|
|
}
|
|
|
|
bool CommandHasObjectBeenBroken( int iObjectID, bool networked )
|
|
{
|
|
const CObject *pObj = CTheScripts::GetEntityToQueryFromGUID<CObject>(iObjectID);
|
|
|
|
if (pObj)
|
|
{
|
|
// If we want to fetch the networked value instead of the local one
|
|
if (networked)
|
|
{
|
|
if(pObj->GetNetworkObject() && pObj->GetNetworkObject()->GetObjectType() == NET_OBJ_TYPE_OBJECT)
|
|
{
|
|
CNetObjObject *netObjObject = SafeCast(CNetObjObject, pObj->GetNetworkObject());
|
|
|
|
if(netObjObject)
|
|
{
|
|
return netObjObject->IsObjectDamaged();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pObj->IsObjectDamaged())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const u32 SearchFlag_Exterior = 0x01;
|
|
const u32 SearchFlag_Interior = 0x02;
|
|
|
|
bool CommandHasClosestObjectOfTypeBeenBroken(const scrVector & scrVecCoors, float Radius, int ObjectModelHashKey, s32 SearchFlags)
|
|
{
|
|
Vector3 VecCoors = Vector3(scrVecCoors);
|
|
|
|
bool bResult = false;
|
|
|
|
float NewX = VecCoors.x;
|
|
float NewY = VecCoors.y;
|
|
float NewZ = VecCoors.z;
|
|
|
|
if (NewZ <= INVALID_MINIMUM_WORLD_Z)
|
|
{
|
|
NewZ = WorldProbe::FindGroundZForCoord(TOP_SURFACE, NewX, NewY);
|
|
}
|
|
|
|
fwModelId ObjectModelId;
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) ObjectModelHashKey, &ObjectModelId); // ignores return value
|
|
if (SCRIPT_VERIFY(ObjectModelId.IsValid(), "HAS_CLOSEST_OBJECT_OF_TYPE_BEEN_BROKEN - this is not a valid model index"))
|
|
{
|
|
ClosestObjectDataStruct ClosestObjectData;
|
|
ClosestObjectData.fClosestDistanceSquared = Radius * Radius * 4.0f; // set this to larger than the scan range (remember it's squared distance)
|
|
ClosestObjectData.pClosestObject = NULL;
|
|
|
|
ClosestObjectData.CoordToCalculateDistanceFrom = Vector3(NewX, NewY, NewZ);
|
|
|
|
ClosestObjectData.ModelIndexToCheck = ObjectModelId.GetModelIndex();
|
|
ClosestObjectData.bCheckModelIndex = true;
|
|
ClosestObjectData.bCheckStealableFlag = false;
|
|
|
|
ClosestObjectData.nOwnedByMask = 0xFFFFFFFF;
|
|
|
|
s32 SearchLocFlags = SEARCH_LOCATION_EXTERIORS|SEARCH_LOCATION_INTERIORS;
|
|
if (scriptVerifyf( (SearchFlags & (SEARCH_LOCATION_EXTERIORS|SEARCH_LOCATION_INTERIORS) ) != 0, "HAS_CLOSEST_OBJECT_OF_TYPE_BEEN_BROKEN - no SEARCH_LOCATION_FLAGS have been set"))
|
|
{
|
|
if ((SearchFlags & SearchFlag_Exterior) == 0)
|
|
{
|
|
SearchLocFlags = SEARCH_LOCATION_INTERIORS; // Search interiors only
|
|
}
|
|
|
|
if ((SearchFlags & SearchFlag_Interior) == 0)
|
|
{
|
|
SearchLocFlags = SEARCH_LOCATION_EXTERIORS; // Search exteriors only
|
|
}
|
|
}
|
|
|
|
fwIsSphereIntersecting testSphere(spdSphere(RCC_VEC3V(ClosestObjectData.CoordToCalculateDistanceFrom), ScalarV(Radius)));
|
|
CGameWorld::ForAllEntitiesIntersecting(&testSphere, CTheScripts::GetClosestObjectCB, (void*) &ClosestObjectData,
|
|
ENTITY_TYPE_MASK_OBJECT, SearchLocFlags,
|
|
SEARCH_LODTYPE_HIGHDETAIL, SEARCH_OPTION_NONE, WORLDREP_SEARCHMODULE_SCRIPT); // |ENTITY_TYPE_MASK_DUMMY_OBJECT
|
|
|
|
if (ClosestObjectData.pClosestObject && ClosestObjectData.pClosestObject->GetIsTypeObject())
|
|
{
|
|
CObject *pObj = (CObject *)ClosestObjectData.pClosestObject;
|
|
if (pObj->IsObjectDamaged())
|
|
{
|
|
bResult = true;
|
|
}
|
|
}
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
bool CommandHasClosestObjectOfTypeBeenCompletelyDestroyed(const scrVector & scrVecCoors, float Radius, int ObjectModelHashKey, s32 SearchFlags)
|
|
{
|
|
Vector3 VecCoors = Vector3(scrVecCoors);
|
|
|
|
bool bResult = false;
|
|
|
|
float NewX = VecCoors.x;
|
|
float NewY = VecCoors.y;
|
|
float NewZ = VecCoors.z;
|
|
|
|
if(NewZ <= INVALID_MINIMUM_WORLD_Z)
|
|
{
|
|
NewZ = WorldProbe::FindGroundZForCoord(TOP_SURFACE, NewX, NewY);
|
|
}
|
|
|
|
fwModelId ObjectModelId;
|
|
CModelInfo::GetBaseModelInfoFromHashKey((u32) ObjectModelHashKey, &ObjectModelId); // ignores return value
|
|
if(SCRIPT_VERIFY(ObjectModelId.IsValid(), "HAS_CLOSEST_OBJECT_OF_TYPE_BEEN_COMPLETELY_DESTROYED - this is not a valid model index"))
|
|
{
|
|
ClosestObjectDataStruct ClosestObjectData;
|
|
ClosestObjectData.fClosestDistanceSquared = Radius * Radius * 4.0f; // set this to larger than the scan range (remember it's squared distance)
|
|
ClosestObjectData.pClosestObject = NULL;
|
|
|
|
ClosestObjectData.CoordToCalculateDistanceFrom = Vector3(NewX, NewY, NewZ);
|
|
|
|
ClosestObjectData.ModelIndexToCheck = ObjectModelId.GetModelIndex();
|
|
ClosestObjectData.bCheckModelIndex = true;
|
|
ClosestObjectData.bCheckStealableFlag = false;
|
|
|
|
ClosestObjectData.nOwnedByMask = 0xFFFFFFFF;
|
|
|
|
s32 SearchLocFlags = SEARCH_LOCATION_EXTERIORS|SEARCH_LOCATION_INTERIORS;
|
|
if(scriptVerifyf( (SearchFlags & (SEARCH_LOCATION_EXTERIORS|SEARCH_LOCATION_INTERIORS) ) != 0, "HAS_CLOSEST_OBJECT_OF_TYPE_BEEN_COMPLETELY_DESTROYED - no SEARCH_LOCATION_FLAGS have been set"))
|
|
{
|
|
if ((SearchFlags & SearchFlag_Exterior) == 0)
|
|
{
|
|
SearchLocFlags = SEARCH_LOCATION_INTERIORS; // Search interiors only
|
|
}
|
|
|
|
if ((SearchFlags & SearchFlag_Interior) == 0)
|
|
{
|
|
SearchLocFlags = SEARCH_LOCATION_EXTERIORS; // Search exteriors only
|
|
}
|
|
}
|
|
|
|
fwIsSphereIntersecting testSphere(spdSphere(RCC_VEC3V(ClosestObjectData.CoordToCalculateDistanceFrom), ScalarV(Radius)));
|
|
CGameWorld::ForAllEntitiesIntersecting(&testSphere, CTheScripts::GetClosestObjectCB, (void*) &ClosestObjectData,
|
|
ENTITY_TYPE_MASK_OBJECT, SearchLocFlags,
|
|
SEARCH_LODTYPE_HIGHDETAIL, SEARCH_OPTION_NONE, WORLDREP_SEARCHMODULE_SCRIPT); // |ENTITY_TYPE_MASK_DUMMY_OBJECT
|
|
|
|
if(ClosestObjectData.pClosestObject && ClosestObjectData.pClosestObject->GetIsTypeObject())
|
|
{
|
|
CObject* pObj = static_cast<CObject*>(ClosestObjectData.pClosestObject);
|
|
Assert(pObj);
|
|
fragInst* pFragInst = pObj->GetFragInst();
|
|
if(SCRIPT_VERIFY(pFragInst, "HAS_CLOSEST_OBJECT_OF_TYPE_BEEN_COMPLETELY_DESTROYED - Doesn't make sense to call this function on a non fraggable object."))
|
|
{
|
|
if(pFragInst->GetCached() && !pFragInst->GetCacheEntry()->IsFurtherBreakable())
|
|
bResult = true;
|
|
}
|
|
}
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
bool CommandGetHasObjectBeenCompletelyDestroyed( int iObjectID )
|
|
{
|
|
const CObject *pObj = CTheScripts::GetEntityToQueryFromGUID<CObject>( iObjectID );
|
|
bool bResult = false;
|
|
|
|
if( pObj )
|
|
{
|
|
fragInst* pFragInst = pObj->GetFragInst();
|
|
|
|
if( SCRIPT_VERIFY( pFragInst, "GET_HAS_OBJECT_BEEN_COMPLETELY_DESTROYED - Doesn't make sense to call this function on a non fraggable object." ) )
|
|
{
|
|
if( pFragInst->GetCached() && !pFragInst->GetCacheEntry()->IsFurtherBreakable() )
|
|
{
|
|
bResult = true;
|
|
}
|
|
}
|
|
}
|
|
return bResult;
|
|
}
|
|
|
|
scrVector CommandGetOffsetFromCoordAndHeadingInWorldCoords( const scrVector & scrVecCoors, float fHeadingDegs, const scrVector & scrOffset )
|
|
{
|
|
const float fHeadingRads = DtoR * fHeadingDegs;
|
|
Vector3 vResult = scrVecCoors;
|
|
Vector3 vRotatedOffset = scrOffset;
|
|
vRotatedOffset.x = scrOffset.x * cosf(fHeadingRads) - scrOffset.y * sinf(fHeadingRads);
|
|
vRotatedOffset.y = scrOffset.y * cosf(fHeadingRads) + scrOffset.x * sinf(fHeadingRads);
|
|
vResult += vRotatedOffset;
|
|
return vResult;
|
|
}
|
|
|
|
|
|
void CommandObjectFragmentBreakChild( int iObjectID, int iComponent, bool bDisappear )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectID);
|
|
|
|
if (pObj)
|
|
{
|
|
if (pObj && pObj->m_nFlags.bIsFrag && pObj->GetCurrentPhysicsInst())
|
|
{
|
|
fragInst* pFragInst = (fragInst*)pObj->GetCurrentPhysicsInst();
|
|
|
|
if (iComponent > -1 && !pFragInst->GetChildBroken(iComponent))
|
|
{
|
|
if (bDisappear)
|
|
{
|
|
pFragInst->DeleteAbove(iComponent);
|
|
}
|
|
else
|
|
{
|
|
Assertf(!pFragInst->IsBreakingDisabled(), "This command will have no effect with breaking disabled. Call SET_DISABLE_BREAKING first");
|
|
if(pFragInst->GetTypePhysics()->GetChild(iComponent)->GetOwnerGroupPointerIndex() == 0)
|
|
{
|
|
pFragInst->BreakOffRoot();
|
|
}
|
|
else
|
|
{
|
|
pFragInst->BreakOffAbove(iComponent);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CommandObjectFragmentDamageChild( int iObjectID, int iComponent, float newHealth )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectID);
|
|
|
|
if (pObj && pObj->m_nFlags.bIsFrag && pObj->GetCurrentPhysicsInst())
|
|
{
|
|
fragInst* pFragInst = (fragInst*)pObj->GetCurrentPhysicsInst();
|
|
fragPhysicsLOD* pFragLOD = pFragInst->GetTypePhysics();
|
|
|
|
if (Verifyf(iComponent > -1 && iComponent < pFragLOD->GetNumChildren(), "Component %d out of range [0, %d) for prop %s", iComponent, pFragLOD->GetNumChildren(), pFragInst->GetType()->GetTuneName()))
|
|
{
|
|
int iGroupIndex = pFragLOD->GetChild(iComponent)->GetOwnerGroupPointerIndex();
|
|
if (!pFragInst->GetCached() || pFragInst->GetCacheEntry()->IsGroupUnbroken(iGroupIndex))
|
|
{
|
|
pFragInst->ReduceGroupDamageHealth(iGroupIndex, newHealth, pFragInst->GetCenterOfMass(), Vec3V(V_ZERO));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CommandObjectFragmentFix( int iObjectID )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectID);
|
|
|
|
if (pObj)
|
|
{
|
|
if (pObj && pObj->m_nFlags.bIsFrag && pObj->GetCurrentPhysicsInst())
|
|
{
|
|
fragInst* pFragInst = (fragInst*)pObj->GetCurrentPhysicsInst();
|
|
if (pFragInst)
|
|
{
|
|
fragCacheEntry *pCacheEntry = pFragInst->GetCacheEntry();
|
|
if (pCacheEntry)
|
|
{
|
|
FRAGCACHEMGR->ReleaseCacheEntry(pCacheEntry);
|
|
}
|
|
pFragInst->PutIntoCache();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CommandFreezePositionOfClosestObjectOfType(const scrVector & scrVecCoors, float Radius, int ObjectModelHashKey, bool bFreezeFlag)
|
|
{
|
|
Vector3 VecCoors = Vector3 (scrVecCoors);
|
|
|
|
CEntity *pClosestObj = CObject::GetPointerToClosestMapObjectForScript(VecCoors.x, VecCoors.y, VecCoors.z, Radius, ObjectModelHashKey);
|
|
if (pClosestObj)
|
|
{
|
|
if (SCRIPT_VERIFY(!NetworkUtils::IsNetworkClone(pClosestObj), "FREEZE_POSITION_OF_CLOSEST_OBJECT_OF_TYPE - Cannot call this command on an entity owned by another machine!"))
|
|
{
|
|
if (SCRIPT_VERIFY(!CModelInfo::GetBaseModelInfoFromHashKey(ObjectModelHashKey, NULL)->GetUsesDoorPhysics(), "FREEZE_POSITION_OF_CLOSEST_OBJECT_OF_TYPE - not allowed on a door"))
|
|
{
|
|
if (SCRIPT_VERIFY(pClosestObj->GetIsTypeObject(), "FREEZE_POSITION_OF_CLOSEST_OBJECT_OF_TYPE - closest object is not a proper object"))
|
|
{
|
|
((CObject *)pClosestObj)->SetFixedPhysics(bFreezeFlag);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CommandTrackObjectVisibility(int ObjectID)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES);
|
|
|
|
if (pObject)
|
|
{
|
|
pObject->SetUseOcclusionQuery(true);
|
|
}
|
|
}
|
|
|
|
|
|
bool CommandIsObjectVisible(int ObjectID)
|
|
{
|
|
bool result = false;
|
|
|
|
const CObject* pObject = CTheScripts::GetEntityToQueryFromGUID<CObject>(ObjectID);
|
|
|
|
if (pObject)
|
|
{
|
|
scriptAssertf(pObject->GetUseOcclusionQuery(), "%s:IS_OBJECT_VISIBLE - Object visibility isn't tracked", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
|
|
fwDrawData* drawData = pObject->GetDrawHandlerPtr();
|
|
if( drawData )
|
|
{
|
|
u32 queryId = drawData->GetOcclusionQueryId();
|
|
|
|
if( queryId )
|
|
{
|
|
int pixelCount = OcclusionQueries::OQGetQueryResult(queryId);
|
|
result = pixelCount > 10; // 10 pixels should be enough for everybody.
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
void CommandSetObjectIsSpecialGolfBall(int ObjectID, bool IsGolfBall)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectID);
|
|
if (pObject)
|
|
{
|
|
pObject->m_nDEflags.bIsGolfBall = IsGolfBall;
|
|
}
|
|
}
|
|
|
|
void CommandSetTakesDamageFromCollidingWithBuildings(int ObjectID, bool bTakesDamage)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectID);
|
|
if (pObject)
|
|
{
|
|
pObject->SetTakesDamageFromCollisionsWithBuildings(bTakesDamage);
|
|
}
|
|
}
|
|
|
|
void CommandAllowDamageEventsForNonNetworkedObjects(bool allow)
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if(NetworkInterface::IsGameInProgress())
|
|
{
|
|
netLoggingInterface *log = &NetworkInterface::GetObjectManager().GetLog();
|
|
if (log)
|
|
{
|
|
NetworkLogUtils::WriteLogEvent(*log, "ALLOW_DAMAGE_EVENTS_FOR_NON_NETWORKED_OBJECTS", "%s", allow ? "TRUE" : "FALSE");
|
|
}
|
|
}
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
CObject::ms_bAllowDamageEventsForNonNetworkedObjects = allow;
|
|
}
|
|
|
|
void CommandSetCutscenesWeaponFlashlightOnThisFrame(int ObjectID, bool bForceOn)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectID);
|
|
if (SCRIPT_VERIFY(pObject, "FORCE_WEAPON_FLASHLIGHT_ON_THIS_FRAME_FOR_CUTSCENE - Could not find entity from ID"))
|
|
{
|
|
if (SCRIPT_VERIFY(pObject->GetWeapon(), "FORCE_WEAPON_FLASHLIGHT_ON_THIS_FRAME_FOR_CUTSCENE - Object is not a weapon"))
|
|
{
|
|
if (pObject->GetWeapon()->GetFlashLightComponent())
|
|
{
|
|
pObject->GetWeapon()->GetFlashLightComponent()->SetForceFlashLightOn(bForceOn);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CommandGetCoordsAndRotationOfClosestObjectOfType(const scrVector & scrVecCoords, float fRadius, int ObjectModelHashKey, Vector3& vOutCoords, Vector3& vOutRot, s32 RotOrder)
|
|
{
|
|
Vector3 VecCoords = Vector3(scrVecCoords);
|
|
|
|
vOutCoords = VEC3_ZERO;
|
|
vOutRot = VEC3_ZERO;
|
|
|
|
CEntity *pClosestObj = CObject::GetPointerToClosestMapObjectForScript(VecCoords.x, VecCoords.y, VecCoords.z, fRadius, ObjectModelHashKey);
|
|
if (pClosestObj)
|
|
{
|
|
if (pClosestObj->GetIsTypeObject())
|
|
{
|
|
// Only return true if the object is a proper object - not a dummy or building
|
|
vOutCoords = VEC3V_TO_VECTOR3(pClosestObj->GetTransform().GetPosition());
|
|
|
|
Matrix34 m = MAT34V_TO_MATRIX34(pClosestObj->GetMatrix());
|
|
vOutRot = CScriptEulers::MatrixToEulers(m, static_cast<EulerAngleOrder>(RotOrder));
|
|
vOutRot *= RtoD;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void ClosestDoorAssertHelper(CDoor::ChangeDoorStateResult result, int ASSERT_ONLY(ObjectModelHashKey), const char * ASSERT_ONLY(functionName))
|
|
{
|
|
// is it a lockable door
|
|
if(result == CDoor::CHANGE_DOOR_STATE_NOT_DOOR)
|
|
{
|
|
scriptAssertf(0, "%s is not a door object\n", CModelInfo::GetBaseModelInfoFromHashKey(ObjectModelHashKey, NULL)->GetModelName());
|
|
}
|
|
else if(result == CDoor::CHANGE_DOOR_STATE_INVALID_OBJECT_TYPE)
|
|
{
|
|
SCRIPT_ASSERT_TWO_STRINGS(0, "%s - closest object must be a dummy or proper object", functionName);
|
|
}
|
|
else if(result == CDoor::CHANGE_DOOR_STATE_IS_BUILDING)
|
|
{
|
|
SCRIPT_ASSERT_TWO_STRINGS(0, "%s - closest object with the given model is a building", functionName);
|
|
}
|
|
else if(result == CDoor::CHANGE_DOOR_STATE_NO_OBJECT)
|
|
{
|
|
SCRIPT_ASSERT_TWO_STRINGS(0, "%s - Couldn't find an object with the given model", functionName);
|
|
}
|
|
}
|
|
|
|
void CommandSetStateOfClosestDoorOfType(int ObjectModelHashKey, const scrVector & scrVecPos, bool bLockState, float fOpenRatio, bool bRemoveSpring)
|
|
{
|
|
if(SCRIPT_VERIFY( CModelInfo::GetBaseModelInfoFromHashKey(ObjectModelHashKey, NULL), "SET_STATE_OF_CLOSEST_DOOR_OF_TYPE - this is not a valid model index"),
|
|
SCRIPT_VERIFY( !NetworkInterface::IsGameInProgress(), "SET_STATE_OF_CLOSEST_DOOR_OF_TYPE - not supported in MP"))
|
|
{
|
|
// Vector3 doorPosition = Vector3(scrVecPos);
|
|
|
|
if (bRemoveSpring && bLockState)
|
|
{
|
|
bRemoveSpring = false;
|
|
SCRIPT_ASSERT(0, "SET_STATE_OF_CLOSEST_DOOR_OF_TYPE - Cannot remove door spring at same time as locking a door");
|
|
}
|
|
|
|
CDoor::ChangeDoorStateResult result = CDoor::ChangeDoorStateForScript(ObjectModelHashKey, Vector3(scrVecPos), NULL, false, bLockState, fOpenRatio, bRemoveSpring);
|
|
|
|
if (result != CDoor::CHANGE_DOOR_STATE_SUCCESS)
|
|
{
|
|
#if __DEV
|
|
if (result == CDoor::CHANGE_DOOR_STATE_NO_OBJECT)
|
|
{
|
|
const char *pModelName = CModelInfo::GetBaseModelInfoFromHashKey(ObjectModelHashKey, NULL)->GetModelName();
|
|
if (!pModelName)
|
|
{
|
|
pModelName = "FAILED LOOKING UP MODEL NAME";
|
|
}
|
|
|
|
float radius = 6.0f;
|
|
CEntity *pClosestObj = CObject::GetPointerToClosestMapObjectForScript(scrVecPos.x, scrVecPos.y, scrVecPos.z, radius, ObjectModelHashKey);
|
|
if (pClosestObj)
|
|
{
|
|
Vector3 position = VEC3V_TO_VECTOR3(pClosestObj->GetTransform().GetPosition());
|
|
scriptAssertf(0, "%s: SET_STATE_OF_CLOSEST_DOOR_OF_TYPE - Couldn't find an object %s at position %f, %f, %f\n"
|
|
"A subsequent search for object %s found it at position %f, %f, %f",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(),
|
|
pModelName,
|
|
scrVecPos.x,
|
|
scrVecPos.y,
|
|
scrVecPos.z,
|
|
pModelName,
|
|
position.x,
|
|
position.y,
|
|
position.z);
|
|
return;
|
|
}
|
|
|
|
scriptAssertf(false, "%s: SET_STATE_OF_CLOSEST_DOOR_OF_TYPE - Couldn't find an object %s at position %f, %f, %f\n",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(),
|
|
pModelName,
|
|
scrVecPos.x,
|
|
scrVecPos.y,
|
|
scrVecPos.z);
|
|
return;
|
|
}
|
|
#endif
|
|
ClosestDoorAssertHelper(result, ObjectModelHashKey, "SET_STATE_OF_CLOSEST_DOOR_OF_TYPE");
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandGetStateOfClosestDoorOfType(int ObjectModelHashKey, const scrVector & scrVecPos, int &bReturnLockState, float &fReturnOpenRatio)
|
|
{
|
|
if(SCRIPT_VERIFY( CModelInfo::GetBaseModelInfoFromHashKey(ObjectModelHashKey, NULL), "GET_STATE_OF_CLOSEST_DOOR_OF_TYPE - this is not a valid model index"))
|
|
{
|
|
bReturnLockState = false;
|
|
fReturnOpenRatio = 0.0f;
|
|
|
|
// is it a lockable door
|
|
CBaseModelInfo *modelInfo = CModelInfo::GetBaseModelInfoFromHashKey(ObjectModelHashKey, NULL);
|
|
if( modelInfo->GetUsesDoorPhysics() )
|
|
{
|
|
Vector3 vecTestPos = Vector3(scrVecPos);
|
|
vecTestPos.x = rage::Floorf(vecTestPos.x + 0.5f);
|
|
vecTestPos.y = rage::Floorf(vecTestPos.y + 0.5f);
|
|
vecTestPos.z = rage::Floorf(vecTestPos.z + 0.5f);
|
|
|
|
// Determine the radius to search within, matching SET_STATE_OF_CLOSEST_DOOR_OF_TYPE.
|
|
// If it's a sliding door that moves as it's being opened, the radius may have to be
|
|
// larger than if it's a rotating one.
|
|
const float radius = CDoor::GetScriptSearchRadius(*modelInfo);
|
|
|
|
CEntity *pClosestObj = CDoor::FindClosestDoor(modelInfo, vecTestPos, radius);
|
|
|
|
if (!pClosestObj)
|
|
{
|
|
pClosestObj = CObject::GetPointerToClosestMapObjectForScript(vecTestPos.x, vecTestPos.y, vecTestPos.z, radius, ObjectModelHashKey);
|
|
// MAGDEMO
|
|
// Removed this assert for the magdemo as its really just a warning that I had made an assert.
|
|
// Assertf(!pClosestObj, "CDoor::FindClosestDoor failed to find the door but GetPointerToClosestMapObjectForScript did add bug for David Ely");
|
|
}
|
|
|
|
if (pClosestObj)
|
|
{
|
|
bReturnLockState = pClosestObj->GetIsAnyFixedFlagSet();
|
|
|
|
if (SCRIPT_VERIFY(pClosestObj->GetIsTypeObject() || pClosestObj->GetIsTypeDummyObject(), "GET_STATE_OF_CLOSEST_DOOR_OF_TYPE - closest object must be a dummy or proper object"))
|
|
{
|
|
if(pClosestObj->GetIsTypeObject() && static_cast<CObject*>(pClosestObj)->IsADoor())
|
|
fReturnOpenRatio = static_cast<CDoor*>(pClosestObj)->GetDoorOpenRatio();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
scriptAssertf(false, "%s is not a door object\n", CModelInfo::GetBaseModelInfoFromHashKey(ObjectModelHashKey, NULL)->GetModelName());
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetLockedUnstreamedInDoorOfType(int ObjectModelHashKey, const scrVector & scrVecPos, bool bLockState, float fAutomaticRate, float fAutomaticDist, float fOpenRatio)
|
|
{
|
|
if (SCRIPT_VERIFY( !NetworkInterface::IsGameInProgress(), "SET_LOCKED_UNSTREAMED_IN_DOOR_OF_TYPE - not supported in MP"))
|
|
{
|
|
Vector3 doorPosition = Vector3(scrVecPos);
|
|
|
|
bool bRemoveSpring = false;
|
|
|
|
bool bSmoothLock = bLockState;
|
|
if(fabsf(fOpenRatio) > SMALL_FLOAT)
|
|
{
|
|
// In this case, the door is not actually requested to close. Make sure
|
|
// to not activate the smooth close-and-lock feature, which could conflict
|
|
// with the request to be open.
|
|
bSmoothLock = false;
|
|
}
|
|
|
|
CDoor::ChangeDoorStateResult result = CDoor::ChangeDoorStateForScript(ObjectModelHashKey, Vector3(scrVecPos), NULL, true, bLockState, fOpenRatio, bRemoveSpring, bSmoothLock, fAutomaticRate, fAutomaticDist, false);
|
|
|
|
if(result != CDoor::CHANGE_DOOR_STATE_SUCCESS)
|
|
{
|
|
//Object not streamed in on host so just set mapped global locked object status
|
|
CDoorSystem::SetLocked(doorPosition, bLockState, fOpenRatio, bRemoveSpring, ObjectModelHashKey, fAutomaticRate, fAutomaticDist, NULL, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandPlayObjectAutoStartAnim(int ObjectIndex)
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObject)
|
|
{
|
|
pObject->PlayAutoStartAnim();
|
|
}
|
|
}
|
|
|
|
void CommandAddDoorToSystem(int doorEnumHash, int hashKey, const scrVector & position, bool useOldOverrides, bool network, bool permanent)
|
|
{
|
|
// atFinalizeHash(u32 key) ... key += (key << 15), thus every valid has must be greater than 1 << 15. This assert exists to catch scripters passing enums instead of hashes
|
|
scriptAssertf(u32(doorEnumHash) > u32(1 << 15), "%s: ADD_DOOR_TO_SYSTEM passed an invalid hash %d", CTheScripts::GetCurrentScriptNameAndProgramCounter(), doorEnumHash);
|
|
|
|
CDoorSystemData* pDoorSystemData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
Vector3 doorPos = Vector3(position.x, position.y, position.z);
|
|
|
|
#if __DEV
|
|
if (!pDoorSystemData)
|
|
{
|
|
CDoorSystemData *pExistingDoorData = CDoorSystem::FindDoorSystemData(doorPos, hashKey, 0.1f);
|
|
if (pExistingDoorData)
|
|
{
|
|
atNonFinalHashString lookUpHash(hashKey);
|
|
scriptAssertf(0, "%s: ADD_DOOR_TO_SYSTEM - a door already exists for model %s at this position %f, %f, %f. It was added by %s",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(),
|
|
lookUpHash.GetCStr(),
|
|
pExistingDoorData->GetPosition().x,
|
|
pExistingDoorData->GetPosition().y,
|
|
pExistingDoorData->GetPosition().z,
|
|
pExistingDoorData->m_pScriptName);
|
|
}
|
|
}
|
|
#endif
|
|
if (pDoorSystemData)
|
|
{
|
|
if (!doorPos.IsClose(pDoorSystemData->GetPosition(), 0.1f))
|
|
{
|
|
scriptAssertf(0, "%s: ADD_DOOR_TO_SYSTEM - a door already exists with this enum hash but has a different position %f, %f, %f. It was added by %s",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(),
|
|
pDoorSystemData->GetPosition().x,
|
|
pDoorSystemData->GetPosition().y,
|
|
pDoorSystemData->GetPosition().z,
|
|
pDoorSystemData->m_pScriptName);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (NetworkInterface::IsGameInProgress() && network)
|
|
{
|
|
if (permanent)
|
|
{
|
|
scriptAssertf(0, "%s: ADD_DOOR_TO_SYSTEM - door is flagged as networked and permanent, permanent doors cannot be networked as they are not attached to the script", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
network = false;
|
|
}
|
|
|
|
if (!CTheScripts::GetCurrentGtaScriptHandlerNetwork() || !CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent())
|
|
{
|
|
scriptAssertf(0, "%s: ADD_DOOR_TO_SYSTEM - a non-networked script cannot add doors during MP", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
return;
|
|
}
|
|
|
|
if (CNetObjDoor::GetPool()->GetNoOfFreeSpaces() == 0)
|
|
{
|
|
scriptAssertf(0, "%s: ADD_DOOR_TO_SYSTEM - ran out of networked doors (max: %d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), CNetObjDoor::GetPool()->GetSize());
|
|
return;
|
|
}
|
|
|
|
if (!CTheScripts::GetCurrentGtaScriptHandlerNetwork()->GetNetworkComponent()->IsHostLocal())
|
|
{
|
|
scriptAssertf(0, "%s: ADD_DOOR_TO_SYSTEM - a non-script host cannot add networked doors to the system", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
return;
|
|
}
|
|
|
|
if (!CNetworkObjectPopulationMgr::CanRegisterObject(NET_OBJ_TYPE_DOOR, true))
|
|
{
|
|
scriptAssertf(0, "%s: ADD_DOOR_TO_SYSTEM - no free ids or ran out of networked doors (max allowed: %d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), MAX_NUM_NETOBJDOORS);
|
|
return;
|
|
}
|
|
}
|
|
|
|
pDoorSystemData = CDoorSystem::AddDoor(doorEnumHash, hashKey, doorPos);
|
|
if (pDoorSystemData)
|
|
{
|
|
pDoorSystemData->SetUseOldOverrides(useOldOverrides);
|
|
|
|
if (permanent)
|
|
{
|
|
pDoorSystemData->SetPermanentState();
|
|
}
|
|
|
|
if (NetworkInterface::IsGameInProgress() && !permanent)
|
|
{
|
|
if (!network)
|
|
{
|
|
pDoorSystemData->SetPersistsWithoutNetworkObject();
|
|
}
|
|
|
|
// only register with the script handler in MP, not sure what this would break in SP! The SP scripts may not be expecting the doors to be
|
|
// cleaned up when the script ends
|
|
if (!pDoorSystemData->GetScriptHandler())
|
|
{
|
|
CTheScripts::GetCurrentGtaScriptHandler()->RegisterNewScriptObject(static_cast<scriptHandlerObject&>(*pDoorSystemData), true, network);
|
|
}
|
|
|
|
NetworkInterface::RegisterScriptDoor(*pDoorSystemData, network);
|
|
}
|
|
|
|
OutputScriptState(doorEnumHash, "Command - %s", "ADD_DOOR_TO_SYSTEM");
|
|
}
|
|
}
|
|
|
|
void CommandRemoveDoorFromSystem(int doorEnumHash, bool bLock = false)
|
|
{
|
|
CDoorSystemData* pDoorSystemData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
scriptAssertf(pDoorSystemData, "%s: REMOVE_DOOR_FROM_SYSTEM - the door has not been added to the door system", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
|
|
if (pDoorSystemData)
|
|
{
|
|
if (pDoorSystemData->GetScriptHandler() && pDoorSystemData->GetScriptHandler()->GetScriptId() != CTheScripts::GetCurrentGtaScriptHandler()->GetScriptId())
|
|
{
|
|
scriptAssertf(pDoorSystemData, "%s: REMOVE_DOOR_FROM_SYSTEM - the door is controlled by another script", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
return;
|
|
}
|
|
|
|
if (pDoorSystemData->GetNetworkObject())
|
|
{
|
|
if (pDoorSystemData->GetNetworkObject()->IsClone() || pDoorSystemData->GetNetworkObject()->IsPendingOwnerChange())
|
|
{
|
|
scriptAssertf(pDoorSystemData, "%s: REMOVE_DOOR_FROM_SYSTEM - the door is not locally controlled", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
return;
|
|
}
|
|
|
|
NetworkInterface::UnregisterScriptDoor(*pDoorSystemData);
|
|
}
|
|
else
|
|
{
|
|
if (pDoorSystemData->GetScriptHandler())
|
|
{
|
|
pDoorSystemData->GetScriptHandler()->UnregisterScriptObject(static_cast<scriptHandlerObject&>(*pDoorSystemData));
|
|
}
|
|
}
|
|
|
|
if (CDoor* pDoor = pDoorSystemData->GetDoor())
|
|
{
|
|
pDoor->SetDoorControlFlag(CDoor::DOOR_CONTROL_FLAGS_LOCK_WHEN_REMOVED, bLock);
|
|
}
|
|
|
|
pDoorSystemData->SetFlagForRemoval();
|
|
OutputScriptState(doorEnumHash, "Command - %s", "REMOVE_DOOR_FROM_SYSTEM");
|
|
|
|
}
|
|
}
|
|
|
|
void CommandDoorSystemSetState(int doorEnumHash, int doorState, bool network, bool flushState)
|
|
{
|
|
#if __BANK
|
|
if (CDoor::sm_IngnoreScriptSetDoorStateCommands)
|
|
{
|
|
return;
|
|
}
|
|
#endif
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
#if __BANK
|
|
if (sm_debugDooorSystemEnumHash == doorEnumHash || (pDoor && pDoor->GetDoor() && pDoor->GetDoor() == g_PickerManager.GetSelectedEntity()))
|
|
{
|
|
if (sm_breakOnSelectedDoorSetState)
|
|
{
|
|
__debugbreak();
|
|
}
|
|
}
|
|
|
|
#endif
|
|
OutputScriptState(doorEnumHash, "Command - %s, state %s, network %s, flushState %s", "DOOR_SYSTEM_SET_DOOR_STATE", CDoorSystemData::GetDoorStateName((DoorScriptState)doorState), network ? "true" : "false", flushState ? "true" : "false");
|
|
|
|
SCRIPT_ASSERT(pDoor, "Door hash supplied failed find a door");
|
|
|
|
if (pDoor)
|
|
{
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
netObject* pNetObj = pDoor->GetNetworkObject();
|
|
if (pNetObj)
|
|
{
|
|
if (!scriptVerifyf(!pNetObj->IsClone() && !pNetObj->IsPendingOwnerChange(), "%s : DOOR_SYSTEM_SET_DOOR_STATE - the door is controlled by another machine", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return;
|
|
}
|
|
|
|
network = true;
|
|
}
|
|
else if (network && pDoor->GetPersistsWithoutNetworkObject())
|
|
{
|
|
// don't start networking if the state of the door is not changing
|
|
if (pDoor->GetPendingState() != DOORSTATE_INVALID)
|
|
{
|
|
if (pDoor->GetPendingState() == doorState)
|
|
{
|
|
network = false;
|
|
}
|
|
}
|
|
else if (pDoor->GetState() == doorState)
|
|
{
|
|
network = false;
|
|
}
|
|
}
|
|
|
|
// start networking the door if it has changed from its initial state
|
|
if (!pNetObj && network)
|
|
{
|
|
if (CNetObjDoor::GetPool()->GetNoOfFreeSpaces() == 0)
|
|
{
|
|
scriptAssertf(0, "%s: DOOR_SYSTEM_SET_DOOR_STATE - ran out of networked doors (max: %d)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), CNetObjDoor::GetPool()->GetSize());
|
|
network = false;
|
|
}
|
|
|
|
if (pDoor->GetPermanentState())
|
|
{
|
|
scriptAssertf(0, "%s: DOOR_SYSTEM_SET_DOOR_STATE - Permanent doors cannot be networked", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
network = false;
|
|
}
|
|
|
|
if (network)
|
|
{
|
|
// we have to trigger a network event here, to request that the door is networked
|
|
CRequestDoorEvent::Trigger(*pDoor, doorState);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
gnetDebug3("DOOR_SYSTEM_SET_DOOR_STATE - %d setting pending state to: %d from: %s", doorEnumHash, doorState, CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
pDoor->SetPendingState((DoorScriptState)doorState);
|
|
|
|
if ((int)pDoor->GetState() != doorState || pDoor->GetStateNeedsToBeFlushed() || flushState)
|
|
{
|
|
CDoorSystem::SetPendingStateOnDoor(*pDoor);
|
|
}
|
|
}
|
|
}
|
|
|
|
int CommandDoorSystemGetState(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "DOOR_SYSTEM_GET_DOOR_STATE: Door hash supplied failed find a door");
|
|
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_DOOR_STATE");
|
|
|
|
if (pDoor)
|
|
{
|
|
return (int)pDoor->GetState();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int CommandDoorSystemGetPendingState(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "DOOR_SYSTEM_GET_DOOR_PENDING_STATE: Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_DOOR_PENDING_STATE");
|
|
|
|
if (pDoor)
|
|
{
|
|
return (int)pDoor->GetPendingState();
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void CommandDoorSystemSetAutomaticRate(int doorEnumHash, float automaticRate, bool network, bool flushState)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s, automaticRate %.2f, network %s, flushstate %s", "DOOR_SYSTEM_SET_AUTOMATIC_RATE", automaticRate, network ? "true" : "false", flushState ? "true" : "false");
|
|
|
|
if (pDoor)
|
|
{
|
|
netObject* pNetObj = pDoor->GetNetworkObject();
|
|
|
|
if (pNetObj)
|
|
{
|
|
if (!scriptVerifyf(!pNetObj->IsClone() && !pNetObj->IsPendingOwnerChange(), "%s : DOOR_SYSTEM_SET_AUTOMATIC_RATE - the door is controlled by another machine", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
pDoor->SetAutomaticRate(automaticRate);
|
|
|
|
if (flushState)
|
|
{
|
|
CommandDoorSystemSetState(doorEnumHash, pDoor->GetState(), network, flushState);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CommandDoorSystemSetAutomaticDistance(int doorEnumHash, float automaticDistance, bool network, bool flushState)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s, automaticDistance %.2f, network %s, flushstate %s", "DOOR_SYSTEM_SET_AUTOMATIC_DISTANCE", automaticDistance, network ? "true" : "false", flushState ? "true" : "false");
|
|
|
|
if (pDoor)
|
|
{
|
|
netObject* pNetObj = pDoor->GetNetworkObject();
|
|
|
|
if (pNetObj)
|
|
{
|
|
if (!scriptVerifyf(!pNetObj->IsClone() && !pNetObj->IsPendingOwnerChange(), "%s : DOOR_SYSTEM_SET_AUTOMATIC_DISTANCE - the door is controlled by another machine", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
pDoor->SetAutomaticDistance(automaticDistance);
|
|
|
|
if (flushState)
|
|
{
|
|
CommandDoorSystemSetState(doorEnumHash, pDoor->GetState(), network, flushState);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandDoorSystemSetOpenRatio(int doorEnumHash, float openRatio, bool network, bool flushState)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s, openRatio %.2f, network %s, flushstate %s", "DOOR_SYSTEM_SET_OPEN_RATIO", openRatio, network ? "true" : "false", flushState ? "true" : "false");
|
|
|
|
if (pDoor)
|
|
{
|
|
netObject* pNetObj = pDoor->GetNetworkObject();
|
|
|
|
if (pNetObj)
|
|
{
|
|
if (!scriptVerifyf(!pNetObj->IsClone() && !pNetObj->IsPendingOwnerChange(), "%s : DOOR_SYSTEM_SET_OPEN_RATIO - the door is controlled by another machine", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
pDoor->SetTargetRatio(openRatio);
|
|
|
|
if (flushState)
|
|
{
|
|
CommandDoorSystemSetState(doorEnumHash, pDoor->GetState(), network, flushState);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
float CommandDoorSystemGetAutomaticRate(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pDoorData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoorData, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_AUTOMATIC_RATE");
|
|
|
|
if (pDoorData)
|
|
{
|
|
CDoor *pDoor = pDoorData->GetDoor();
|
|
if (pDoor)
|
|
{
|
|
return pDoor->GetAutomaticRate();
|
|
}
|
|
else
|
|
{
|
|
return pDoorData->GetAutomaticRate();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
float CommandDoorSystemGetAutomaticDistance(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pDoorData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoorData, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_SET_AUTOMATIC_DISTANCE");
|
|
|
|
if (pDoorData)
|
|
{
|
|
CDoor *pDoor = pDoorData->GetDoor();
|
|
if (pDoor)
|
|
{
|
|
return pDoor->GetAutomaticDist();
|
|
}
|
|
else
|
|
{
|
|
return pDoorData->GetAutomaticDistance();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
float CommandDoorSystemGetOpenRatio(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pDoorData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoorData, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_OPEN_RATIO");
|
|
|
|
if (pDoorData)
|
|
{
|
|
CDoor *pDoor = pDoorData->GetDoor();
|
|
if (pDoor)
|
|
{
|
|
return pDoor->GetDoorOpenRatio();
|
|
}
|
|
else
|
|
{
|
|
return pDoorData->GetTargetRatio();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
|
|
void CommandDoorSystemSetUnsprung(int doorEnumHash, bool unsprung, bool network, bool flushState)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s, unsprung %s, network %s, flushstate %s", "DOOR_SYSTEM_SET_UNSPRUNG", unsprung ? "true" : "false", network ? "true" : "false", flushState ? "true" : "false");
|
|
|
|
if (pDoor)
|
|
{
|
|
netObject* pNetObj = pDoor->GetNetworkObject();
|
|
|
|
if (pNetObj)
|
|
{
|
|
if (!scriptVerifyf(!pNetObj->IsClone() && !pNetObj->IsPendingOwnerChange(), "%s : DOOR_SYSTEM_SET_UNSPRUNG - the door is controlled by another machine", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
pDoor->SetUnsprung(unsprung);
|
|
|
|
if (flushState)
|
|
{
|
|
CommandDoorSystemSetState(doorEnumHash, pDoor->GetState(), network, flushState);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
bool CommandDoorSystemGetUnsprung(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
SCRIPT_ASSERT(pData, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_UNSPRUNG");
|
|
if (pData)
|
|
{
|
|
return pData->GetUnsprung();
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CommandDoorSystemSetHoldOpen(int doorEnumHash, bool holdOpen)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s, holdOpen %s", "DOOR_SYSTEM_SET_HOLD_OPEN", holdOpen ? "true" : "false");
|
|
|
|
if (pDoor)
|
|
{
|
|
netObject* pNetObj = pDoor->GetNetworkObject();
|
|
|
|
if (pNetObj)
|
|
{
|
|
if (!scriptVerifyf(!pNetObj->IsClone() && !pNetObj->IsPendingOwnerChange(), "%s : DOOR_SYSTEM_SET_HOLD_OPEN - the door is controlled by another machine", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
pDoor->SetHoldOpen(holdOpen);
|
|
}
|
|
|
|
}
|
|
|
|
bool CommandDoorSystemGetHoldOpen(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
SCRIPT_ASSERT(pData, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_HOLD_OPEN");
|
|
if (pData)
|
|
{
|
|
return pData->GetHoldOpen();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CommandIsDoorRegisteredWithSystem(int doorEnumHash)
|
|
{
|
|
OutputScriptState(doorEnumHash, "Command - %s", "IS_DOOR_REGISTERED_WITH_SYSTEM");
|
|
bool bRegistered = CDoorSystem::GetDoorData(doorEnumHash) != NULL;
|
|
|
|
return bRegistered;
|
|
}
|
|
|
|
bool CommandIsDoorClosed(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pDoorData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
OutputScriptState(doorEnumHash, "Command - %s", "IS_DOOR_CLOSED");
|
|
|
|
bool bClosed = true;
|
|
|
|
if (scriptVerifyf(pDoorData, "%s: IS_DOOR_CLOSED - door does not exist", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
CDoor* pDoor = pDoorData->GetDoor();
|
|
|
|
if (pDoor)
|
|
{
|
|
bClosed = pDoor->IsDoorShut();
|
|
}
|
|
else if (pDoorData->GetNetworkObject() && pDoorData->GetNetworkObject()->IsClone())
|
|
{
|
|
bClosed = static_cast<CNetObjDoor*>(pDoorData->GetNetworkObject())->IsClosed();
|
|
}
|
|
else if (pDoorData->GetPendingState() != DOORSTATE_INVALID)
|
|
{
|
|
bClosed = pDoorData->GetPendingState() != DOORSTATE_FORCE_OPEN_THIS_FRAME;
|
|
}
|
|
else
|
|
{
|
|
bClosed = pDoorData->GetState() != DOORSTATE_FORCE_OPEN_THIS_FRAME;
|
|
}
|
|
}
|
|
|
|
return bClosed;
|
|
}
|
|
|
|
bool CommandIsDoorFullyOpen(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pDoorData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
OutputScriptState(doorEnumHash, "Command - %s", "IS_DOOR_FULLY_OPEN");
|
|
bool bFullyOpen = true;
|
|
|
|
if (scriptVerifyf(pDoorData, "%s: IS_DOOR_FULLY_OPEN - door does not exist", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
if (pDoorData->GetDoor())
|
|
{
|
|
bFullyOpen = (pDoorData->GetDoor()->GetDoorOpenRatio() > 0.99f);
|
|
}
|
|
else if (pDoorData->GetNetworkObject() && pDoorData->GetNetworkObject()->IsClone())
|
|
{
|
|
bFullyOpen = static_cast<CNetObjDoor*>(pDoorData->GetNetworkObject())->IsFullyOpen();
|
|
}
|
|
else if (pDoorData->GetPendingState() != DOORSTATE_INVALID)
|
|
{
|
|
bFullyOpen = pDoorData->GetPendingState() == DOORSTATE_FORCE_OPEN_THIS_FRAME;
|
|
}
|
|
else
|
|
{
|
|
bFullyOpen = pDoorData->GetState() == DOORSTATE_FORCE_OPEN_THIS_FRAME;
|
|
}
|
|
}
|
|
|
|
return bFullyOpen;
|
|
}
|
|
|
|
void CommandOpenAllBarriersForRace(bool snapOpen)
|
|
{
|
|
#if __BANK
|
|
if (sm_debugDooorSystemEnumHash != -1)
|
|
{
|
|
Displayf("Command - OPEN_ALL_BARRIERS_FOR_RACE %s", snapOpen ? "true" : "false");
|
|
}
|
|
#endif
|
|
CDoor::OpenAllBarriersForRace(snapOpen);
|
|
}
|
|
|
|
void CommandCloseAllBarriersOpenedForRace()
|
|
{
|
|
#if __BANK
|
|
if (sm_debugDooorSystemEnumHash != -1)
|
|
{
|
|
Displayf("Command - CLOSE_ALL_BARRIERS_FOR_RACE");
|
|
}
|
|
#endif
|
|
CDoor::CloseAllBarriersOpenedForRace();
|
|
}
|
|
|
|
void CommandDoorSystemSetOpenForRaces(int doorEnumHash, bool open)
|
|
{
|
|
CDoorSystemData *pDoor = CDoorSystem::GetDoorData(doorEnumHash);
|
|
|
|
SCRIPT_ASSERT(pDoor, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s, open %s", "DOOR_SYSTEM_SET_DOOR_OPEN_FOR_RACES", open ? "true" : "false");
|
|
|
|
if (pDoor)
|
|
{
|
|
netObject* pNetObj = pDoor->GetNetworkObject();
|
|
|
|
if (pNetObj)
|
|
{
|
|
if (!scriptVerifyf(!pNetObj->IsClone() && !pNetObj->IsPendingOwnerChange(), "%s : DOOR_SYSTEM_SET_DOOR_OPEN_FOR_RACES - the door is controlled by another machine", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
pDoor->SetOpenForRaces(open);
|
|
|
|
if (pDoor->GetDoor() && CDoor::AreDoorsOpenForRacing())
|
|
{
|
|
if (open)
|
|
{
|
|
pDoor->GetDoor()->OpenDoor();
|
|
}
|
|
else
|
|
{
|
|
pDoor->GetDoor()->CloseDoor();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
bool CommandDoorSystemGetOpenForRaces(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
SCRIPT_ASSERT(pData, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_DOOR_OPEN_FOR_RACES");
|
|
if (pData)
|
|
{
|
|
return pData->GetOpenForRaces();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CommandDoorSetAlwaysPush( int doorEnumHash, bool push )
|
|
{
|
|
CDoorSystemData *pData = CDoorSystem::GetDoorData( doorEnumHash );
|
|
SCRIPT_ASSERT( pData, "Door hash supplied failed find a door" );
|
|
OutputScriptState( doorEnumHash, "Command - %s", "DOOR_SET_ALWAYS_PUSH" );
|
|
|
|
if( pData && pData->GetDoor() )
|
|
{
|
|
pData->GetDoor()->SetAlwaysPush( push );
|
|
}
|
|
}
|
|
|
|
void CommandDoorSetAlwaysPushVehicles(int ObjectID , bool pushVehicles)
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectID);
|
|
if (pObject && pObject->IsADoor())
|
|
{
|
|
static_cast<CDoor *>(pObject)->SetAlwaysPushVehicles(pushVehicles);
|
|
}
|
|
}
|
|
|
|
bool CommandDoorSystemGetIsPhysicsLoaded(int doorEnumHash)
|
|
{
|
|
CDoorSystemData *pData = CDoorSystem::GetDoorData(doorEnumHash);
|
|
SCRIPT_ASSERT(pData, "Door hash supplied failed find a door");
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_GET_IS_PHYSICS_LOADED");
|
|
if (pData)
|
|
{
|
|
return pData->GetDoor() != NULL;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CommandDoorSystemFindExistingDoor(const scrVector & scrVecPos, int ObjectModelHashKey, int &doorEnumHash)
|
|
{
|
|
CDoorSystemData *pData = CDoorSystem::FindDoorSystemData(scrVecPos, ObjectModelHashKey, 0.5f);
|
|
if (pData)
|
|
{
|
|
doorEnumHash = pData->GetEnumHash();
|
|
OutputScriptState(doorEnumHash, "Command - %s", "DOOR_SYSTEM_FIND_EXISTING_DOOR");
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CommandDoesObjectOfTypeExistAtCoords(const scrVector & scrVecPos, float Radius, int ObjectModelHashKey, bool checkPhysicsExists)
|
|
{
|
|
Vector3 VecCoors = Vector3 (scrVecPos);
|
|
|
|
bool bObjectExists = false;
|
|
CEntity *pClosestObj = CObject::GetPointerToClosestMapObjectForScript(VecCoors.x, VecCoors.y, VecCoors.z, Radius, ObjectModelHashKey);
|
|
if (pClosestObj)
|
|
{
|
|
if (pClosestObj->GetIsTypeObject())
|
|
{ // Only return true if the object is a proper object - not a dummy or building
|
|
if (checkPhysicsExists)
|
|
{
|
|
bObjectExists = pClosestObj->GetCurrentPhysicsInst() != 0;
|
|
}
|
|
else
|
|
{
|
|
bObjectExists = true;
|
|
}
|
|
}
|
|
}
|
|
return bObjectExists;
|
|
}
|
|
|
|
bool CommandIsPointInAngledArea(const scrVector & scrVecPoint, const scrVector & scrVecCoors1, const scrVector & scrVecCoors2, float DistanceP1toP4, bool HighlightArea, bool bCheck3d)
|
|
{
|
|
Vector3 VecPoint = Vector3(scrVecPoint);
|
|
Vector3 VecCoors1 = Vector3(scrVecCoors1);
|
|
Vector3 VecCoors2 = Vector3(scrVecCoors2);
|
|
|
|
if(!bCheck3d)
|
|
{
|
|
VecCoors1.z = INVALID_MINIMUM_WORLD_Z;
|
|
VecCoors2.z = VecCoors1.z;
|
|
}
|
|
|
|
return PointInAngledAreaCheck(bCheck3d, VecPoint, VecCoors1, VecCoors2, DistanceP1toP4, HighlightArea);
|
|
}
|
|
|
|
|
|
void CommandSetObjectAsStealable(int ObjectID, bool IsStealable )
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectID);
|
|
if (pObject)
|
|
{
|
|
pObject->m_nObjectFlags.bIsStealable = IsStealable;
|
|
pObject->m_nObjectFlags.bCanBePickedUp = IsStealable;
|
|
}
|
|
}
|
|
|
|
bool CommandHasObjectBeenUprooted( int ObjectID )
|
|
{
|
|
bool bResult = false;
|
|
|
|
const CObject *pObject = CTheScripts::GetEntityToQueryFromGUID<CObject>(ObjectID);
|
|
if (pObject)
|
|
{
|
|
if(pObject)
|
|
{
|
|
bResult = bool(pObject->m_nObjectFlags.bHasBeenUprooted);
|
|
}
|
|
}
|
|
return (bResult);
|
|
}
|
|
|
|
bool CommandDoesPickupExist( int PickupID )
|
|
{
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
scriptHandlerObject* pObject = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(PickupID);
|
|
|
|
if (pObject && static_cast<CGameScriptHandlerObject*>(pObject)->GetType() == SCRIPT_HANDLER_OBJECT_TYPE_PICKUP)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CommandDoesPickupObjectExist( int PickupID )
|
|
{
|
|
bool bObjExists = false;
|
|
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
scriptHandlerObject* pObject = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(PickupID);
|
|
|
|
if (pObject)
|
|
{
|
|
if (scriptVerifyf(static_cast<CGameScriptHandlerObject*>(pObject)->GetType() == SCRIPT_HANDLER_OBJECT_TYPE_PICKUP, "DOES_PICKUP_OBJECT_EXIST - This is not a pickup id"))
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(PickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"DOES_PICKUP_OBJECT_EXIST - Pickup does not exist" ))
|
|
{
|
|
bObjExists = !pPlacement->GetIsCollected() && !pPlacement->GetHasPickupBeenDestroyed();
|
|
|
|
if (pPlacement->GetHiddenWhenUncollectable() && !pPlacement->CanCollectScript())
|
|
{
|
|
bObjExists = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bObjExists;
|
|
}
|
|
|
|
int CommandGetPickupObject( int PickupID )
|
|
{
|
|
int objectIndex = -1;
|
|
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
scriptHandlerObject* pObject = CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(PickupID);
|
|
|
|
if (pObject)
|
|
{
|
|
if (scriptVerifyf(static_cast<CGameScriptHandlerObject*>(pObject)->GetType() == SCRIPT_HANDLER_OBJECT_TYPE_PICKUP, "GET_PICKUP_OBJECT - This is not a pickup id"))
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(PickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"GET_PICKUP_OBJECT - Pickup does not exist" ))
|
|
{
|
|
if (pPlacement->GetPickup())
|
|
{
|
|
objectIndex = CTheScripts::GetGUIDFromEntity(*pPlacement->GetPickup());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return objectIndex;
|
|
}
|
|
|
|
bool CommandIsObjectAPickup(int ObjectIndex)
|
|
{
|
|
bool bIsPickup = false;
|
|
|
|
const CObject *pObj = CTheScripts::GetEntityToQueryFromGUID<CObject>(ObjectIndex);
|
|
|
|
bIsPickup = pObj && pObj->m_nObjectFlags.bIsPickUp;
|
|
|
|
return bIsPickup;
|
|
}
|
|
|
|
bool CommandIsObjectAPortablePickup(int ObjectIndex)
|
|
{
|
|
bool bIsPortablePickup = false;
|
|
|
|
const CObject *pObj = CTheScripts::GetEntityToQueryFromGUID<CObject>(ObjectIndex);
|
|
|
|
if (pObj && pObj->m_nObjectFlags.bIsPickUp)
|
|
{
|
|
const CPickup* pPickup = SafeCast(const CPickup, pObj);
|
|
|
|
bIsPortablePickup = pPickup->IsFlagSet(CPickup::PF_Portable);
|
|
}
|
|
|
|
return bIsPortablePickup;
|
|
}
|
|
|
|
bool CommandDoesPickupOfTypeExistInArea( int PickupHash, const scrVector & scrVecCoors, float radius)
|
|
{
|
|
PickupHash = ConvertOldPickupTypeToHash(PickupHash);
|
|
|
|
bool bPickupExists = false;
|
|
|
|
Vector3 VecCoords = Vector3 (scrVecCoors);
|
|
|
|
radius *= radius;
|
|
|
|
s32 i = CPickup::GetPool()->GetSize();
|
|
|
|
while(i--)
|
|
{
|
|
CPickup* pPickup = CPickup::GetPool()->GetSlot(i);
|
|
|
|
if (pPickup && pPickup->GetPickupHash() == (u32)PickupHash)
|
|
{
|
|
Vector3 diff = VEC3V_TO_VECTOR3(pPickup->GetTransform().GetPosition()) - VecCoords;
|
|
|
|
if (diff.Mag2() <= radius)
|
|
{
|
|
bPickupExists = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bPickupExists;
|
|
}
|
|
|
|
|
|
void CommandSetNearestBuildingAnimRate(const scrVector & scrVecCentreCoors, float Radius, s32 ModelHashKey, float Rate, int RateFlags)
|
|
{
|
|
Vector3 VecCentre = Vector3(scrVecCentreCoors);
|
|
|
|
CEntity *pEntity = CObject::GetPointerToClosestMapObjectForScript(VecCentre.x, VecCentre.y, VecCentre.z, Radius, ModelHashKey, ENTITY_TYPE_MASK_ANIMATED_BUILDING|ENTITY_TYPE_MASK_BUILDING|ENTITY_TYPE_MASK_OBJECT|ENTITY_TYPE_MASK_DUMMY_OBJECT);
|
|
if (pEntity)
|
|
{
|
|
if (SCRIPT_VERIFY(pEntity->GetIsTypeAnimatedBuilding(), "SET_NEAREST_BUILDING_ANIM_RATE - Closest entity is not a building!"))
|
|
{
|
|
CAnimatedBuilding *pAnimatedBuilding = static_cast< CAnimatedBuilding * >(pEntity);
|
|
CMoveAnimatedBuilding &moveAnimatedBuilding = pAnimatedBuilding->GetMoveAnimatedBuilding();
|
|
CEntity *pLod = static_cast< CEntity * >(pAnimatedBuilding->GetRootLod());
|
|
if(SCRIPT_VERIFY(pLod, "SET_NEAREST_BUILDING_ANIM_RATE - Could not get root lod from animated building!"))
|
|
{
|
|
/* Clip */
|
|
CBaseModelInfo *pBaseModelInfo = pAnimatedBuilding->GetBaseModelInfo();
|
|
if(SCRIPT_VERIFY(pBaseModelInfo, "SET_NEAREST_BUILDING_ANIM_RATE - Could not get base model info!"))
|
|
{
|
|
strLocalIndex clipDictionaryIndex = strLocalIndex(pBaseModelInfo->GetClipDictionaryIndex());
|
|
if(SCRIPT_VERIFY(g_ClipDictionaryStore.IsValidSlot(clipDictionaryIndex), "SET_NEAREST_BUILDING_ANIM_RATE - Could not get clip dictionary index from base model info!"))
|
|
{
|
|
const crClip *pClip = fwAnimManager::GetClipIfExistsByDictIndex(clipDictionaryIndex.Get(), pBaseModelInfo->GetHashKey());
|
|
if(SCRIPT_VERIFY(pClip, "SET_NEAREST_BUILDING_ANIM_RATE - Could not get clip!"))
|
|
{
|
|
/* Rate */
|
|
float rate = Rate;
|
|
if((RateFlags & AB_RATE_RANDOM) != 0)
|
|
{
|
|
const CClipEventTags::CRandomizeRateProperty *pRateProp = CClipEventTags::FindProperty< CClipEventTags::CRandomizeRateProperty >(pClip, CClipEventTags::RandomizeRate);
|
|
if(SCRIPT_VERIFY(pRateProp, "SET_NEAREST_BUILDING_ANIM_RATE - Could not get rate property from clip!"))
|
|
{
|
|
rate = pRateProp->PickRandomRate((u32)(size_t)pLod);
|
|
}
|
|
}
|
|
moveAnimatedBuilding.SetRate(rate);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Displayf("Failed to find building\n");
|
|
}
|
|
}
|
|
|
|
void CommandGetNearestBuildingAnimRate(const scrVector & scrVecCentreCoors, float Radius, s32 ModelHashKey, float &ReturnRate)
|
|
{
|
|
Vector3 VecCentre = Vector3(scrVecCentreCoors);
|
|
|
|
CEntity *pEntity = CObject::GetPointerToClosestMapObjectForScript(VecCentre.x, VecCentre.y, VecCentre.z, Radius, ModelHashKey, ENTITY_TYPE_MASK_ANIMATED_BUILDING|ENTITY_TYPE_MASK_BUILDING|ENTITY_TYPE_MASK_OBJECT|ENTITY_TYPE_MASK_DUMMY_OBJECT);
|
|
if (pEntity)
|
|
{
|
|
if (SCRIPT_VERIFY(pEntity->GetIsTypeAnimatedBuilding(), "PLAY_NEAREST_BUILDING_ANIM - Closest entity is not a building"))
|
|
{
|
|
CAnimatedBuilding *pAnimatedBuilding = static_cast< CAnimatedBuilding * >(pEntity);
|
|
CMoveAnimatedBuilding &moveAnimatedBuilding = pAnimatedBuilding->GetMoveAnimatedBuilding();
|
|
|
|
/* Rate */
|
|
ReturnRate = moveAnimatedBuilding.GetRate();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Displayf("Failed to find building\n");
|
|
}
|
|
}
|
|
|
|
void CommandSetNearestBuildingAnimPhase(const scrVector & scrVecCentreCoors, float Radius, s32 ModelHashKey, float Phase, int PhaseFlags)
|
|
{
|
|
Vector3 VecCentre = Vector3(scrVecCentreCoors);
|
|
|
|
CEntity *pEntity = CObject::GetPointerToClosestMapObjectForScript(VecCentre.x, VecCentre.y, VecCentre.z, Radius, ModelHashKey, ENTITY_TYPE_MASK_ANIMATED_BUILDING|ENTITY_TYPE_MASK_BUILDING|ENTITY_TYPE_MASK_OBJECT|ENTITY_TYPE_MASK_DUMMY_OBJECT);
|
|
if (pEntity)
|
|
{
|
|
if (SCRIPT_VERIFY(pEntity->GetIsTypeAnimatedBuilding(), "SET_NEAREST_BUILDING_ANIM_PHASE - Closest entity is not a building!"))
|
|
{
|
|
CAnimatedBuilding *pAnimatedBuilding = static_cast< CAnimatedBuilding * >(pEntity);
|
|
CMoveAnimatedBuilding &moveAnimatedBuilding = pAnimatedBuilding->GetMoveAnimatedBuilding();
|
|
CEntity *pLod = static_cast< CEntity * >(pAnimatedBuilding->GetRootLod());
|
|
if(SCRIPT_VERIFY(pLod, "SET_NEAREST_BUILDING_ANIM_PHASE - Could not get root lod from animated building!"))
|
|
{
|
|
/* Clip */
|
|
CBaseModelInfo *pBaseModelInfo = pAnimatedBuilding->GetBaseModelInfo();
|
|
if(SCRIPT_VERIFY(pBaseModelInfo, "SET_NEAREST_BUILDING_ANIM_PHASE - Could not get base model info!"))
|
|
{
|
|
strLocalIndex clipDictionaryIndex = strLocalIndex(pBaseModelInfo->GetClipDictionaryIndex());
|
|
if(SCRIPT_VERIFY(g_ClipDictionaryStore.IsValidSlot(clipDictionaryIndex), "SET_NEAREST_BUILDING_ANIM_PHASE - Could not get clip dictionary index from base model info!"))
|
|
{
|
|
const crClip *pClip = fwAnimManager::GetClipIfExistsByDictIndex(clipDictionaryIndex.Get(), pBaseModelInfo->GetHashKey());
|
|
if(SCRIPT_VERIFY(pClip, "SET_NEAREST_BUILDING_ANIM_PHASE - Could not get clip!"))
|
|
{
|
|
/* Phase */
|
|
float phase = Phase;
|
|
if((PhaseFlags & AB_PHASE_RANDOM) != 0)
|
|
{
|
|
const CClipEventTags::CRandomizeStartPhaseProperty *pPhaseProp = CClipEventTags::FindProperty< CClipEventTags::CRandomizeStartPhaseProperty >(pClip, CClipEventTags::RandomizeStartPhase);
|
|
if(SCRIPT_VERIFY(pPhaseProp, "SET_NEAREST_BUILDING_ANIM_PHASE - Could not get phase property from clip!"))
|
|
{
|
|
phase = pPhaseProp->PickRandomStartPhase((u32)(size_t)pLod);
|
|
}
|
|
}
|
|
phase = phase - Floorf(phase);
|
|
moveAnimatedBuilding.SetPhase(phase);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Displayf("Failed to find building\n");
|
|
}
|
|
}
|
|
|
|
void CommandGetNearestBuildingAnimPhase(const scrVector & scrVecCentreCoors, float Radius, s32 ModelHashKey, float &ReturnPhase)
|
|
{
|
|
Vector3 VecCentre = Vector3(scrVecCentreCoors);
|
|
|
|
CEntity *pEntity = CObject::GetPointerToClosestMapObjectForScript(VecCentre.x, VecCentre.y, VecCentre.z, Radius, ModelHashKey, ENTITY_TYPE_MASK_ANIMATED_BUILDING|ENTITY_TYPE_MASK_BUILDING|ENTITY_TYPE_MASK_OBJECT|ENTITY_TYPE_MASK_DUMMY_OBJECT);
|
|
if (pEntity)
|
|
{
|
|
if (SCRIPT_VERIFY(pEntity->GetIsTypeAnimatedBuilding(), "PLAY_NEAREST_BUILDING_ANIM - Closest entity is not a building"))
|
|
{
|
|
CAnimatedBuilding *pAnimatedBuilding = static_cast< CAnimatedBuilding * >(pEntity);
|
|
CMoveAnimatedBuilding &moveAnimatedBuilding = pAnimatedBuilding->GetMoveAnimatedBuilding();
|
|
|
|
/* Phase */
|
|
ReturnPhase = moveAnimatedBuilding.GetPhase();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Displayf("Failed to find building\n");
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectAllowLowLodBuoyancy(int ObjectIndex, bool bAllow)
|
|
{
|
|
CObject* pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if(pObj)
|
|
{
|
|
pObj->m_Buoyancy.m_buoyancyFlags.bScriptLowLodOverride = bAllow ? 1 : 0;
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectPhysicsParams(int ObjectIndex, float fMass, float fGravityFactor, const scrVector & vecTranslationDamping, const scrVector & vecRotationDamping, float fCollisionMargin, float fMaxAngularSpeed, float fBuoyancyFactor)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
if(SCRIPT_VERIFY(pObj->GetCurrentPhysicsInst(), "SET_OBJECT_PHYSICS_PARAMS - Object doesn't have physics streamed in yet"))
|
|
{
|
|
|
|
CBaseModelInfo *pModelInfo = pObj->GetBaseModelInfo();
|
|
|
|
// check if object still has original physics archetype
|
|
if(pObj->GetCurrentPhysicsInst()->GetArchetype() == pModelInfo->GetPhysics())
|
|
{
|
|
// if so then we need to clone it so that we can modify values
|
|
phArchetypeDamp* pNewArchetype = static_cast<phArchetypeDamp*>(pObj->GetCurrentPhysicsInst()->GetArchetype()->Clone());
|
|
// pass new archetype to the objects physinst -> should have 1 ref only
|
|
pObj->GetCurrentPhysicsInst()->SetArchetype(pNewArchetype);
|
|
}
|
|
|
|
phArchetypeDamp* pGtaArchetype = static_cast<phArchetypeDamp*>(pObj->GetCurrentPhysicsInst()->GetArchetype());
|
|
|
|
// option to set mass
|
|
if(fMass > -1.0f)
|
|
{
|
|
if (SCRIPT_VERIFY(fMass>0.0f, "SET_OBJECT_PHYSICS_PARAMS - Mass must be greater than zero (or -1.0f)"))
|
|
{
|
|
pObj->SetMass(fMass);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Assert(pModelInfo->GetPhysics());
|
|
// Reset mass to normal
|
|
if(pModelInfo->GetPhysics())
|
|
{
|
|
pGtaArchetype->SetMass(pModelInfo->GetPhysics()->GetMass());
|
|
}
|
|
else
|
|
{
|
|
pGtaArchetype->SetMass(1.0f);
|
|
}
|
|
}
|
|
|
|
// option to set gravity factor
|
|
if(fGravityFactor > -1.0f)
|
|
{
|
|
pGtaArchetype->SetGravityFactor(fGravityFactor);
|
|
}
|
|
|
|
// Option to set buoyancy factor.
|
|
if(fBuoyancyFactor > -1.0f)
|
|
{
|
|
pGtaArchetype->SetBuoyancyFactor(fBuoyancyFactor);
|
|
}
|
|
|
|
if(vecTranslationDamping.x > -1.0f)
|
|
pGtaArchetype->ActivateDamping(phArchetypeDamp::LINEAR_C, Vector3(vecTranslationDamping.x, vecTranslationDamping.x, vecTranslationDamping.x));
|
|
if(vecTranslationDamping.y > -1.0f)
|
|
pGtaArchetype->ActivateDamping(phArchetypeDamp::LINEAR_V, Vector3(vecTranslationDamping.y, vecTranslationDamping.y, vecTranslationDamping.y));
|
|
if(vecTranslationDamping.z > -1.0f)
|
|
pGtaArchetype->ActivateDamping(phArchetypeDamp::LINEAR_V2, Vector3(vecTranslationDamping.z, vecTranslationDamping.z, vecTranslationDamping.z));
|
|
|
|
if(vecRotationDamping.x > -1.0f)
|
|
pGtaArchetype->ActivateDamping(phArchetypeDamp::ANGULAR_C, Vector3(vecRotationDamping.x, vecRotationDamping.x, vecRotationDamping.x));
|
|
if(vecRotationDamping.y > -1.0f)
|
|
pGtaArchetype->ActivateDamping(phArchetypeDamp::ANGULAR_V, Vector3(vecRotationDamping.y, vecRotationDamping.y, vecRotationDamping.y));
|
|
if(vecRotationDamping.z > -1.0f)
|
|
pGtaArchetype->ActivateDamping(phArchetypeDamp::ANGULAR_V2, Vector3(vecRotationDamping.z, vecRotationDamping.z, vecRotationDamping.z));
|
|
|
|
if(fCollisionMargin > 0.0f && fCollisionMargin < 0.1f)
|
|
{
|
|
// when we cloned the archetype, the bound will have been cloned as well
|
|
// so we can do what we like to it, so long as it's not a composite - only want to set margin on geometry bounds for now anyway
|
|
if(pGtaArchetype->GetBound()->GetType()==phBound::GEOMETRY)
|
|
{
|
|
phBoundGeometry* pBoundGeom = static_cast<phBoundGeometry*>(pGtaArchetype->GetBound());
|
|
pBoundGeom->SetMarginAndShrink(fCollisionMargin);
|
|
}
|
|
else
|
|
scriptAssertf(false, "%s:SET_OBJECT_PHYSICS_PARAMS - Collision margin can only be set on geometry bounds", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
}
|
|
|
|
if(fMaxAngularSpeed > 1.0f)
|
|
{
|
|
pGtaArchetype->SetMaxAngSpeed(fMaxAngularSpeed);
|
|
}
|
|
|
|
if(pObj->GetNetworkObject() && pObj->GetNetworkObject()->GetObjectType() == NET_OBJ_TYPE_OBJECT)
|
|
{
|
|
CNetObjObject *netObjObject = SafeCast(CNetObjObject, pObj->GetNetworkObject());
|
|
netObjObject->SetUsingScriptedPhysicsParams(true);
|
|
|
|
scriptAssertf(fMass <= -1.0f &&
|
|
fGravityFactor <= -1.0f &&
|
|
vecRotationDamping.x <= -1.0f &&
|
|
vecRotationDamping.y <= -1.0f &&
|
|
vecRotationDamping.z <= -1.0f &&
|
|
fCollisionMargin <= -1.0f &&
|
|
fMaxAngularSpeed <= -1.0f &&
|
|
fBuoyancyFactor <= -1.0f, "%s:SET_OBJECT_PHYSICS_PARAMS - Currently only setting translational damping is synced in network games!", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
float GetObjFragmentDamagedHealth(const CObject *pObj, bool bHealthPercentageByMass)
|
|
{
|
|
float fReturnHealth = 1.0f;
|
|
if(pObj && pObj->m_nFlags.bIsFrag && pObj->GetCurrentPhysicsInst())
|
|
{
|
|
fragInst* pFragInst = (fragInst*)pObj->GetCurrentPhysicsInst();
|
|
if(pFragInst->GetCached())
|
|
{
|
|
if(bHealthPercentageByMass)
|
|
{
|
|
fReturnHealth = pFragInst->GetArchetype()->GetMass() / pFragInst->GetTypePhysics()->GetTotalUndamagedMass();
|
|
}
|
|
else
|
|
{
|
|
int nNumGroups = pFragInst->GetTypePhysics()->GetNumChildGroups();
|
|
int nNumGroupsAlive = 0;
|
|
for(int i=0; i<nNumGroups; i++)
|
|
{
|
|
if(pFragInst->GetCacheEntry()->GetHierInst()->groupBroken->IsClear(i))
|
|
nNumGroupsAlive++;
|
|
}
|
|
|
|
if(nNumGroups > 0)
|
|
fReturnHealth = float(nNumGroupsAlive) / float(nNumGroups);
|
|
}
|
|
}
|
|
}
|
|
|
|
return fReturnHealth;
|
|
}
|
|
|
|
float CommandGetObjectFragmentDamageHealth(int ObjectIndex, bool bHealthPercentageByMass)
|
|
{
|
|
float fFragmentHealth = 1.0f;
|
|
const CObject *pObj = CTheScripts::GetEntityToQueryFromGUID<CObject>(ObjectIndex);
|
|
|
|
if(pObj)
|
|
{
|
|
fFragmentHealth = GetObjFragmentDamagedHealth(pObj, bHealthPercentageByMass);
|
|
}
|
|
|
|
return fFragmentHealth;
|
|
}
|
|
|
|
bool HasObjFragmentRootBeenDamaged(CObject *pObj)
|
|
{
|
|
if (pObj)
|
|
{
|
|
fragInst* pFragInst = pObj->GetFragInst();
|
|
if(pFragInst && pFragInst->GetCached())
|
|
{
|
|
if(pFragInst->GetTypePhysics()->GetAllChildren()[0]->GetDamagedEntity()
|
|
&& pFragInst->GetCacheEntry()->GetHierInst()->groupInsts[0].IsDamaged())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool HasObjBeenDamagedByPed(const CObject *pObj, int PedIndex)
|
|
{
|
|
bool bReturnValue = false;
|
|
|
|
const CPed *pPed = NULL;
|
|
if (PedIndex != NULL_IN_SCRIPTING_LANGUAGE)
|
|
{
|
|
pPed = CTheScripts::GetEntityToQueryFromGUID<CPed>(PedIndex, CTheScripts::GUID_ASSERT_FLAGS_NO_DEAD_CHECK);
|
|
if(!pPed)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pObj && pObj->HasBeenDamagedByAnyPed())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if(pObj && pObj->GetNetworkObject())
|
|
{
|
|
bReturnValue = NetworkInterface::HasBeenDamagedBy(pObj->GetNetworkObject(), pPed);
|
|
}
|
|
else
|
|
{
|
|
if (pObj && pPed)
|
|
{
|
|
if (pObj->HasBeenDamagedByEntity(const_cast<CPed*>(pPed)))
|
|
{
|
|
bReturnValue = true;
|
|
}
|
|
if (pPed->GetPedConfigFlag( CPED_CONFIG_FLAG_InVehicle ))
|
|
{
|
|
scriptAssertf(pPed->GetMyVehicle(), "%s:HasObjBeenDamagedByPed - Character is not in a vehicle", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
if (pObj->HasBeenDamagedByEntity(pPed->GetMyVehicle()))
|
|
{
|
|
bReturnValue = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bReturnValue;
|
|
}
|
|
|
|
|
|
void CommandSetArrowAboveBlippedPickups(bool bOn)
|
|
{
|
|
eBLIP_DISPLAY_TYPE blipDisplayType;
|
|
|
|
if (bOn)
|
|
blipDisplayType = BLIP_DISPLAY_BOTH;
|
|
else
|
|
blipDisplayType = BLIP_DISPLAY_BLIPONLY;
|
|
|
|
CMiniMapBlip *pSimpleBlip = CMiniMap::GetBlipFromActualId(CMiniMap::GetActualSimpleBlipId());
|
|
|
|
if (pSimpleBlip)
|
|
{
|
|
CMiniMap::SetBlipDisplayValue(pSimpleBlip, blipDisplayType);
|
|
}
|
|
}
|
|
|
|
bool CommandIsAnyObjectNearPoint(const scrVector & scrVecPoint, float radius, bool bConsiderScriptCreatedObjectsOnly)
|
|
{
|
|
Vector3 vPoint = Vector3 (scrVecPoint);
|
|
float radiusSqr = radius*radius;
|
|
ScalarV vRadiusSqr = ScalarVFromF32(radiusSqr);
|
|
|
|
for(s32 i=0; i<CObject::GetPool()->GetSize(); i++)
|
|
{
|
|
CObject *pObject = CObject::GetPool()->GetSlot(i);
|
|
|
|
if (pObject && (!bConsiderScriptCreatedObjectsOnly || pObject->IsAScriptEntity()))
|
|
{
|
|
// Vector3 v = pObject->GetPosition() - vPoint;
|
|
Vec3V v = pObject->GetTransform().GetPosition() - RCC_VEC3V(vPoint);
|
|
|
|
// if (v.Mag2() <= radiusSqr)
|
|
if (IsLessThanOrEqualAll(MagSquared(v), vRadiusSqr))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CommandIsObjectNearPoint(int modelHash, const scrVector & scrVecPoint, float radius)
|
|
{
|
|
if(SCRIPT_VERIFY( CModelInfo::GetBaseModelInfoFromHashKey(modelHash, NULL), "IS_OBJECT_NEAR_POINT - this is not a valid model hash"))
|
|
{
|
|
Vector3 vPoint = Vector3 (scrVecPoint);
|
|
float radiusSqr = radius*radius;
|
|
ScalarV vRadiusSqr = ScalarVFromF32(radiusSqr);
|
|
for(s32 i=0; i<CObject::GetPool()->GetSize(); i++)
|
|
{
|
|
CObject *pObject = CObject::GetPool()->GetSlot(i);
|
|
if (pObject)
|
|
{
|
|
CBaseModelInfo *pModelInfo = pObject->GetBaseModelInfo();
|
|
if( pModelInfo && pModelInfo->GetModelNameHash() == (u32)modelHash )
|
|
{
|
|
Vec3V v = pObject->GetTransform().GetPosition() - RCC_VEC3V(vPoint);
|
|
if (IsLessThanOrEqualAll(MagSquared(v), vRadiusSqr))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CommandRequestObjectHighDetailModel(int iObjectIndex)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectIndex);
|
|
|
|
if (pObject)
|
|
{
|
|
Displayf("Requesting high detail object (this doesn't do anything - see a coder)");
|
|
}
|
|
}
|
|
|
|
void CommandRemoveObjectHighDetailModel(int iObjectIndex)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(iObjectIndex);
|
|
|
|
if (pObject)
|
|
{
|
|
Displayf("Removing high detail object (this doesn't do anything - see a coder)");
|
|
}
|
|
}
|
|
|
|
/*
|
|
enum eCompEntityState {
|
|
CE_STATE_INVALID = -1,
|
|
CE_STATE_INIT = 0,
|
|
CE_STATE_SYNC_STARTING = 1,
|
|
CE_STATE_STARTING = 2,
|
|
CE_STATE_START = 3,
|
|
CE_STATE_PRIMING = 4,
|
|
CE_STATE_PRIMED = 5,
|
|
CE_STATE_START_ANIM = 6,
|
|
CE_STATE_ANIMATING = 7,
|
|
CE_STATE_SYNC_ENDING = 8,
|
|
CE_STATE_ENDING = 9,
|
|
CE_STATE_END = 10,
|
|
CE_STATE_RESET = 11,
|
|
CE_STATE_PAUSED = 12,
|
|
CE_STATE_RESUME = 13,
|
|
};
|
|
*/
|
|
|
|
void CommandSetCompositeEntityState(int iCompEntityIndex, int targetState)
|
|
{
|
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(iCompEntityIndex);
|
|
|
|
if (SCRIPT_VERIFY (pCompEntity, "SetCompositeEntityState - Object doesn't exist"))
|
|
{
|
|
pCompEntity->SetModifiedBy(CTheScripts::GetCurrentScriptName());
|
|
switch(targetState)
|
|
{
|
|
case CE_STATE_STARTING:
|
|
pCompEntity->SetToStarting();
|
|
break;
|
|
case CE_STATE_PRIMING:
|
|
pCompEntity->SetToPriming();
|
|
break;
|
|
case CE_STATE_START_ANIM:
|
|
if (SCRIPT_VERIFY ((pCompEntity->GetState() == CE_STATE_PRIMED), "SetCompositeEntityState - can't start anim if not primed")){
|
|
pCompEntity->TriggerAnim();
|
|
}
|
|
break;
|
|
case CE_STATE_ENDING:
|
|
pCompEntity->SetToEnding();
|
|
break;
|
|
case CE_STATE_RESET:
|
|
pCompEntity->Reset();
|
|
break;
|
|
case CE_STATE_PAUSED:
|
|
pCompEntity->PauseAnimAt(0.0f); // pause immediately
|
|
break;
|
|
case CE_STATE_RESUME:
|
|
pCompEntity->ResumeAnim();
|
|
break;
|
|
default:
|
|
scriptAssertf(false, "[script] State (%d) passed to object (%s) is not handled.", targetState, pCompEntity->GetModelName());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
void CommandPauseCompositeEntityAtPhase(int iCompEntityIndex, float targetPhase)
|
|
{
|
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(iCompEntityIndex);
|
|
|
|
if (SCRIPT_VERIFY (pCompEntity, "PauseCompositeEntityAtPhase - Object doesn't exist"))
|
|
{
|
|
if (SCRIPT_VERIFY(targetPhase > 0.0f && targetPhase < 1.0f, "PauseCompositeEntityAtPhase - invalid phase")){
|
|
pCompEntity->PauseAnimAt(targetPhase);
|
|
}
|
|
}
|
|
}
|
|
float CommandGetCompEntityAnimationPhase(int iCompEntityIndex)
|
|
{
|
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(iCompEntityIndex);
|
|
|
|
if (SCRIPT_VERIFY (pCompEntity, "GET_RAYFIRE_MAP_OBJECT_PHASE - Object doesn't exist"))
|
|
{
|
|
if(pCompEntity->GetState() == CE_STATE_ANIMATING)
|
|
{
|
|
CObject* pAnimatedObj = pCompEntity->GetPrimaryAnimatedObject();
|
|
if(pAnimatedObj)
|
|
{
|
|
if(pAnimatedObj->GetAnimDirector())
|
|
{
|
|
CMoveObject & move = pAnimatedObj->GetMoveObject();
|
|
return move.GetClipHelper().GetPhase();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return 0.0f;
|
|
}
|
|
|
|
s32 CommandGetCompositeEntityState(int iCompEntityIndex)
|
|
{
|
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(iCompEntityIndex);
|
|
|
|
if (SCRIPT_VERIFY (pCompEntity, "GetCompositeEntityState - Object doesn't exist"))
|
|
{
|
|
return(pCompEntity->GetState());
|
|
}
|
|
|
|
return(-1);
|
|
}
|
|
|
|
s32 CommandGetCompositeEntityAt(const scrVector & scrVecCoors, float Radius, const char* pRayFireName )
|
|
{
|
|
u32 ModelHashKey = atStringHash(pRayFireName);
|
|
u32 poolSize = CCompEntity::GetPool()->GetSize();
|
|
|
|
Vector3 vCoors = Vector3(scrVecCoors);
|
|
ScalarV vRadiusSquared = ScalarVFromF32(Radius*Radius);
|
|
|
|
for(u32 i=0; i< poolSize; i++){
|
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetSlot(i);
|
|
|
|
if (pCompEntity){
|
|
CBaseModelInfo* pModelInfo = pCompEntity->GetBaseModelInfo();
|
|
if (pModelInfo && (pModelInfo->GetHashKey() == (u32)ModelHashKey)){
|
|
// Vector3 delta = (pCompEntity->GetPosition()) - (Vector3)scrVecCoors;
|
|
// if (delta.Mag2() < (Radius*Radius)){
|
|
if (IsLessThanAll(DistSquared(pCompEntity->GetTransform().GetPosition(), RCC_VEC3V(vCoors)), vRadiusSquared))
|
|
{
|
|
s32 returnCompEntityIndex = CCompEntity::GetPool()->GetIndex(pCompEntity);
|
|
scriptAssertf(returnCompEntityIndex >= 0, "invalid index returned for %s",pCompEntity->GetModelName());
|
|
return(returnCompEntityIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(NULL_IN_SCRIPTING_LANGUAGE);
|
|
}
|
|
|
|
//need a hash version to be called by the cutscene code
|
|
s32 CommandGetCompositeEntityAtInternal(const scrVector & scrVecCoors, float Radius, const atHashString& RayFireHash )
|
|
{
|
|
u32 ModelHashKey = RayFireHash.GetHash();
|
|
u32 poolSize = CCompEntity::GetPool()->GetSize();
|
|
|
|
Vector3 vCoors = Vector3(scrVecCoors);
|
|
ScalarV vRadiusSquared = ScalarVFromF32(Radius*Radius);
|
|
|
|
for(u32 i=0; i< poolSize; i++){
|
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetSlot(i);
|
|
|
|
if (pCompEntity){
|
|
CBaseModelInfo* pModelInfo = pCompEntity->GetBaseModelInfo();
|
|
if (pModelInfo && (pModelInfo->GetHashKey() == (u32)ModelHashKey)){
|
|
// Vector3 delta = (pCompEntity->GetPosition()) - (Vector3)scrVecCoors;
|
|
// if (delta.Mag2() < (Radius*Radius)){
|
|
if (IsLessThanAll(DistSquared(pCompEntity->GetTransform().GetPosition(), RCC_VEC3V(vCoors)), vRadiusSquared))
|
|
{
|
|
s32 returnCompEntityIndex = CCompEntity::GetPool()->GetIndex(pCompEntity);
|
|
scriptAssertf(returnCompEntityIndex >= 0, "invalid index returned for %s",pCompEntity->GetModelName());
|
|
return(returnCompEntityIndex);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return(NULL_IN_SCRIPTING_LANGUAGE);
|
|
}
|
|
|
|
bool CommandDoesRayFireMapObjectExist(int iCompEntityIndex)
|
|
{
|
|
if (scriptVerifyf(iCompEntityIndex >= 0, "DOES_RAYFIRE_MAP_OBJECT_EXIST - called with invalid argument"))
|
|
{
|
|
CCompEntity* pCompEntity = CCompEntity::GetPool()->GetAt(iCompEntityIndex);
|
|
|
|
if(pCompEntity)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CommandSetPickupRegenerationTime( int iPickupID, int regenTime )
|
|
{
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"SET_PICKUP_REGENERATION_TIME - Pickup does not exist" ))
|
|
{
|
|
if (SCRIPT_VERIFY(!pPlacement->GetIsCollected(), "SET_PICKUP_REGENERATION_TIME - Pickup has already been collected" ) &&
|
|
SCRIPT_VERIFY(!pPlacement->GetNetworkObject() || !pPlacement->GetNetworkObject()->HasBeenCloned(), "SET_PICKUP_REGENERATION_TIME - Can't set this once the pickup has been created on other machines. You must set this immediately after the pickup is created"))
|
|
{
|
|
pPlacement->SetRegenerationTime((u32)regenTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandForcePickupRegenerate(int iPickupID)
|
|
{
|
|
if (scriptVerify(CTheScripts::GetCurrentGtaScriptHandler()))
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
if (scriptVerifyf(pPlacement, "Placement with id: %d can not be found", iPickupID)
|
|
&& !pPlacement->IsNetworkClone())
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
NetworkLogUtils::WriteLogEvent(NetworkInterface::GetObjectManager().GetLog(), "FORCE_PICKUP_REGENERATE", "%s", pPlacement->GetNetworkObject()? pPlacement->GetNetworkObject()->GetLogName():"N/A");
|
|
NetworkInterface::GetObjectManager().GetLog().WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
CPickupManager::ForcePlacementFromRegenerationListToRegenerate(*pPlacement);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetPlayerPermittedToCollectPickupsOfType(int PlayerIndex, int iPickupHash, bool bAllow)
|
|
{
|
|
iPickupHash = ConvertOldPickupTypeToHash(iPickupHash);
|
|
|
|
CNetGamePlayer* pPlayer = CTheScripts::FindNetworkPlayer(PlayerIndex);
|
|
|
|
if (pPlayer)
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
NetworkLogUtils::WriteLogEvent(NetworkInterface::GetObjectManager().GetLog(), "SET_PLAYER_PERMITTED_TO_COLLECT_PICKUPS_OF_TYPE", "");
|
|
NetworkInterface::GetObjectManager().GetLog().WriteDataValue("Player", "%d", PlayerIndex);
|
|
NetworkInterface::GetObjectManager().GetLog().WriteDataValue("Type", "0x%x", iPickupHash);
|
|
NetworkInterface::GetObjectManager().GetLog().WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
NetworkInterface::GetObjectManager().GetLog().WriteDataValue("Allow", "%s", bAllow ? "True" : "False");
|
|
}
|
|
#endif
|
|
if (bAllow)
|
|
{
|
|
CPickupManager::AllowCollectionForPlayer((u32)iPickupHash, pPlayer->GetPhysicalPlayerIndex());
|
|
|
|
Assertf(!CPickupManager::IsCollectionProhibited((u32)iPickupHash, pPlayer->GetPhysicalPlayerIndex()), "SET_PLAYER_PERMITTED_TO_COLLECT_PICKUPS_OF_TYPE failed to allow collection");
|
|
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress() && CPickupManager::IsCollectionProhibited((u32)iPickupHash, pPlayer->GetPhysicalPlayerIndex()))
|
|
{
|
|
NetworkInterface::GetObjectManager().GetLog().WriteDataValue("Fail", "Collection still prohibited");
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
CPickupManager::ProhibitCollectionForPlayer((u32)iPickupHash, pPlayer->GetPhysicalPlayerIndex());
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetLocalPlayerPermittedToCollectPickupsWithModel(int modelHashKey, bool bAllow)
|
|
{
|
|
if (bAllow)
|
|
{
|
|
CPickupManager::RemoveProhibitedPickupModelCollection(modelHashKey, CTheScripts::GetCurrentScriptName());
|
|
}
|
|
else
|
|
{
|
|
CPickupManager::ProhibitPickupModelCollectionForLocalPlayer(modelHashKey, CTheScripts::GetCurrentScriptName());
|
|
}
|
|
}
|
|
|
|
void CommandAllowAllPlayersToCollectPickupsOfType(int iPickupHash)
|
|
{
|
|
iPickupHash = ConvertOldPickupTypeToHash(iPickupHash);
|
|
CPickupManager::RemoveProhibitedCollection((u32)iPickupHash);
|
|
}
|
|
|
|
void CommandSetTeamPickup(int iPickupID, int team)
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"SET_TEAM_PICKUP - Pickup does not exist" ) &&
|
|
SCRIPT_VERIFY(team >=0 && team < MAX_NUM_TEAMS, "SET_TEAM_PICKUP - Invalid team"))
|
|
{
|
|
pPlacement->AddTeamPermit(static_cast<u8>(team));
|
|
}
|
|
}
|
|
|
|
void CommandSetTeamPickupObject(int PickupIndex, int team, bool bSet)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup && SCRIPT_VERIFY(team >=0 && team < MAX_NUM_TEAMS, "SET_TEAM_PICKUP_OBJECT - Invalid team"))
|
|
{
|
|
if (bSet)
|
|
{
|
|
pPickup->AddTeamPermit(static_cast<u8>(team));
|
|
}
|
|
else
|
|
{
|
|
pPickup->RemoveTeamPermit(static_cast<u8>(team));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupGlowForSameTeam(int iPickupID)
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
if (SCRIPT_VERIFY(pPlacement,"SET_PICKUP_GLOW_IN_SAME_TEAM - Pickup does not exist" ))
|
|
{
|
|
pPlacement->SetGlowWhenInSameTeam();
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupObjectGlowForSameTeam(int iPickupID)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(iPickupID);
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetGlowWhenInSameTeam();
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectGlowForSameTeam(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (SCRIPT_VERIFY(pObj, "SET_OBJECT_GLOW_IN_SAME_TEAM - Object does not exist"))
|
|
{
|
|
if(pObj->IsPickup())
|
|
{
|
|
CPickup* pickup = static_cast<CPickup*>(pObj);
|
|
|
|
if(SCRIPT_VERIFY(pickup, "SET_OBJECT_GLOW_IN_SAME_TEAM - Pickup does not exist"))
|
|
{
|
|
pickup->SetGlowWhenInSameTeam();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupObjectGlowWhenUncollectable(int PickupIndex, bool bSet)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetGlowOnProhibitCollection(bSet);
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupGlowOffset(int iPickupID, float offset)
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"SET_PICKUP_GLOW_OFFSET - Pickup does not exist" ))
|
|
{
|
|
pPlacement->SetPickupGlowOffset(offset);
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupObjectGlowOffset(int PickupIndex, float offset, bool bSet)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetGlowOffset(offset);
|
|
pPickup->SetOffsetGlow(bSet);
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupObjectArrowMarker(int PickupIndex, bool bSet)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetArrowMarker(bSet);
|
|
}
|
|
}
|
|
|
|
void CommandAllowPickupObjectArrowMarkerWhenUncollectable(int PickupIndex, bool bSet)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetAllowArrowMarkerWhenUncollectable(bSet);
|
|
}
|
|
}
|
|
|
|
int CommandGetDefaultAmmoForWeaponPickup(int iPickupHash)
|
|
{
|
|
const CPickupData* pPickupData = CPickupDataManager::GetPickupData(iPickupHash);
|
|
|
|
if (SCRIPT_VERIFY(pPickupData,"GET_DEFAULT_AMMO_FOR_WEAPON_PICKUP - Unrecognised pickup type" ))
|
|
{
|
|
for (u32 i=0; i<pPickupData->GetNumRewards(); i++)
|
|
{
|
|
if (pPickupData->GetReward(i)->GetType() == PICKUP_REWARD_TYPE_AMMO)
|
|
{
|
|
return SafeCast(const CPickupRewardAmmo, pPickupData->GetReward(i))->GetAmount();
|
|
}
|
|
}
|
|
|
|
scriptAssertf(0, "GET_DEFAULT_AMMO_FOR_WEAPON_PICKUP - This pickup type is not a weapon pickup type");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CommandSetVehicleWeaponPickupsSharedByPassengers(bool bSet)
|
|
{
|
|
CPickup::SetVehicleWeaponsSharedAmongstPassengers(bSet);
|
|
}
|
|
|
|
void CommandSetPickupGenerationRangeMultiplier(float multiplier)
|
|
{
|
|
CPickupPlacement::SetGenerationRangeMultiplier(multiplier);
|
|
|
|
if (multiplier != 1.0f && CTheScripts::GetCurrentGtaScriptHandler()->GetNumScriptResourcesOfType(CGameScriptResource::SCRIPT_RESOURCE_PICKUP_GENERATION_MULTIPLIER) == 0)
|
|
{
|
|
CScriptResource_PickupGenerationMultiplier pickupMultiplierResource;
|
|
CTheScripts::GetCurrentGtaScriptHandler()->RegisterScriptResource(pickupMultiplierResource);
|
|
}
|
|
}
|
|
|
|
float CommandGetPickupGenerationRangeMultiplier()
|
|
{
|
|
return CPickupPlacement::GetGenerationRangeMultiplier();
|
|
}
|
|
|
|
void CommandSetOnlyAllowAmmoCollectionWhenLow(bool bSet)
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if (NetworkInterface::IsGameInProgress() && bSet != CPickupManager::GetOnlyAllowAmmoCollectionWhenLowOnAmmo())
|
|
{
|
|
char str[10];
|
|
formatf(str, "%s", bSet ? "true" : "false");
|
|
NetworkLogUtils::WriteLogEvent(NetworkInterface::GetObjectManager().GetLog(), "SET_ONLY_ALLOW_AMMO_COLLECTION_WHEN_LOW", str);
|
|
NetworkInterface::GetObjectManager().GetLog().WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptName());
|
|
}
|
|
#endif
|
|
|
|
CPickupManager::SetOnlyAllowAmmoCollectionWhenLowOnAmmo(bSet);
|
|
}
|
|
|
|
void CommandSetPickupUncollectable(int iPickupID, bool bSet)
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"SET_PICKUP_UNCOLLECTABLE - Pickup does not exist" ) &&
|
|
SCRIPT_VERIFY(pPlacement->GetIsMapPlacement(), "SET_PICKUP_UNCOLLECTABLE - Only currently supported for map pickups (PLACEMENT_FLAG_MAP set)"))
|
|
{
|
|
pPlacement->SetUncollectable(bSet);
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupTransparentWhenUncollectable(int iPickupID, bool bSet)
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"SET_PICKUP_TRANSPARENT_WHEN_UNCOLLECTABLE - Pickup does not exist" ) &&
|
|
SCRIPT_VERIFY(pPlacement->GetIsMapPlacement(), "SET_PICKUP_TRANSPARENT_WHEN_UNCOLLECTABLE - Only currently supported for map pickups (PLACEMENT_FLAG_MAP set)"))
|
|
{
|
|
pPlacement->SetTransparentWhenUncollectable(bSet);
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupHiddenWhenUncollectable(int iPickupID, bool bSet)
|
|
{
|
|
CPickupPlacement* pPlacement = static_cast<CPickupPlacement*>(CTheScripts::GetCurrentGtaScriptHandler()->GetScriptObject(iPickupID));
|
|
|
|
if (SCRIPT_VERIFY(pPlacement,"SET_PICKUP_HIDDEN_WHEN_UNCOLLECTABLE - Pickup does not exist" ) &&
|
|
SCRIPT_VERIFY(pPlacement->GetIsMapPlacement(), "SET_PICKUP_HIDDEN_WHEN_UNCOLLECTABLE - Only currently supported for map pickups (PLACEMENT_FLAG_MAP set)"))
|
|
{
|
|
pPlacement->SetHiddenWhenUncollectable(bSet);
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupObjectTransparentWhenUncollectable(int PickupIndex, bool bSet)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetTransparentWhenUncollectable(bSet);
|
|
}
|
|
}
|
|
|
|
void CommandSetPickupObjectAlphaWhenTransparent(int alpha)
|
|
{
|
|
if (SCRIPT_VERIFY(alpha>=0 && alpha<=255,"SET_PICKUP_OBJECT_ALPHA_WHEN_TRANSPARENT - Invalid alpha" ))
|
|
{
|
|
CPickup::PICKUP_ALPHA_WHEN_TRANSPARENT = (u32)alpha;
|
|
}
|
|
}
|
|
|
|
void CommandSetPortablePickupPersist(int PickupIndex, bool toEnable)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup)
|
|
{
|
|
pPickup->SetPortablePickupPersist(toEnable);
|
|
}
|
|
}
|
|
|
|
void CommandAllowPortablePickupToMigrateToNonParticipants(int PickupIndex, bool allow)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup &&
|
|
SCRIPT_VERIFY(pPickup->GetNetworkObject(), "ALLOW_PORTABLE_PICKUP_TO_MIGRATE_TO_NON_PARTICIPANTS - the pickup is not networked") &&
|
|
SCRIPT_VERIFY(pPickup->IsFlagSet(CPickup::PF_Portable), "ALLOW_PORTABLE_PICKUP_TO_MIGRATE_TO_NON_PARTICIPANTS - the pickup is not portable"))
|
|
{
|
|
pPickup->GetNetworkObject()->SetGlobalFlag(CNetObjGame::GLOBALFLAG_SCRIPT_MIGRATION, !allow);
|
|
}
|
|
}
|
|
|
|
void CommandForceActivatePhysicsOnUnfixedPickup(int PickupIndex, bool force)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup &&
|
|
SCRIPT_VERIFY(pPickup->IsFlagSet(CPickup::PF_Portable), "FORCE_PORTABLE_PICKUP_TO_NOT_FIX - the pickup is not portable"))
|
|
{
|
|
pPickup->SetForceActivatePhysicsOnUnfixedPickup(force);
|
|
}
|
|
}
|
|
|
|
void CommandForceActivatePhysicsOnDroppedPickupNearSubmarine(int PickupIndex, bool force)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (pPickup &&
|
|
SCRIPT_VERIFY(pPickup->IsFlagSet(CPickup::PF_Portable), "FORCE_ACTIVATE_PHYSICS_ON_DROPPED_PICKUP_NEAR_SUBMARINE - the pickup is not portable"))
|
|
{
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if(NetworkInterface::IsGameInProgress() && (pPickup->GetForceActivatePhysicsOnDropNearSubmarine() != force))
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "FORCE_ACTIVATE_PHYSICS_ON_DROPPED_PICKUP_NEAR_SUBMARINE", "%s", pPickup->GetLogName());
|
|
log.WriteDataValue("Force", "%s", force?"TRUE":"FALSE");
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
}
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
|
|
pPickup->SetForceActivatePhysicsOnUnfixedPickup(force);
|
|
}
|
|
}
|
|
|
|
void CommandAllowPickupByNonParticipant(int PickupIndex, bool allow)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
|
|
if (SCRIPT_VERIFY(pPickup, "Pickup doesn't exists"))
|
|
{
|
|
pPickup->SetAllowNonScriptParticipantCollect(allow);
|
|
}
|
|
}
|
|
|
|
bool CommandIsPortablePickupCustomColliderReady(int PickupIndex)
|
|
{
|
|
const CPickup* pickup = CTheScripts::GetEntityToQueryFromGUID<CPickup>(PickupIndex);
|
|
if(scriptVerifyf(pickup->IsFlagSet((CPickup::PF_Portable)), "IS_PORTABLE_PICKUP_CUSTOM_COLLIDER_READY called on non portable pickup from: %s", CTheScripts::GetCurrentScriptNameAndProgramCounter()))
|
|
{
|
|
return pickup->IsCustomColliderReady();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CommandPreventCollectionOfPortablePickup(int PickupIndex, bool prevent, bool localOnly)
|
|
{
|
|
CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex, localOnly ? CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES : CTheScripts::GUID_ASSERT_FLAGS_ALL);
|
|
|
|
#if ENABLE_NETWORK_LOGGING
|
|
if(NetworkInterface::IsGameInProgress() && (!pPickup || pPickup->GetProhibitCollection(localOnly) != prevent))
|
|
{
|
|
netLoggingInterface &log = NetworkInterface::GetObjectManager().GetLog();
|
|
NetworkLogUtils::WriteLogEvent(log, "PREVENT_COLLECTION_OF_PORTABLE_PICKUP", "%s", pPickup ? pPickup->GetLogName():"None");
|
|
log.WriteDataValue("Script", "%s", CTheScripts::GetCurrentScriptNameAndProgramCounter());
|
|
log.WriteDataValue("Prevent", "%s", prevent?"TRUE":"FALSE");
|
|
log.WriteDataValue("localOnly", "%s", localOnly?"TRUE":"FALSE");
|
|
}
|
|
#endif // ENABLE_NETWORK_LOGGING
|
|
|
|
if (pPickup)
|
|
{
|
|
if (localOnly)
|
|
{
|
|
pPickup->SetProhibitLocalCollection(prevent);
|
|
}
|
|
else
|
|
{
|
|
pPickup->SetProhibitCollection(prevent);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetEntityFlag_SUPPRESS_SHADOW( int iEntityID, bool bFlag )
|
|
{
|
|
CEntity *pEntity = const_cast<CEntity*>(CTheScripts::GetEntityToQueryFromGUID<CEntity>(iEntityID));
|
|
|
|
if (pEntity)
|
|
{
|
|
fwFlags16& visibilityMask = pEntity->GetRenderPhaseVisibilityMask();
|
|
|
|
if (bFlag) { visibilityMask.ClearFlag( VIS_PHASE_MASK_SHADOWS ); }
|
|
else { visibilityMask.SetFlag( VIS_PHASE_MASK_SHADOWS ); }
|
|
}
|
|
}
|
|
|
|
void CommandSetEntityFlag_RENDER_SMALL_SHADOW( int iEntityID, bool bFlag )
|
|
{
|
|
CEntity *pEntity = const_cast<CEntity*>(CTheScripts::GetEntityToQueryFromGUID<CEntity>(iEntityID));
|
|
|
|
if (pEntity)
|
|
{
|
|
if (bFlag) { pEntity->SetBaseFlag (fwEntity::RENDER_SMALL_SHADOW); }
|
|
else { pEntity->ClearBaseFlag(fwEntity::RENDER_SMALL_SHADOW); }
|
|
}
|
|
}
|
|
|
|
bool CommandIsGarageEmpty(int garageHash, bool onAllMachines, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
|
|
if (onAllMachines)
|
|
{
|
|
return CGarages::IsGarageEmptyOnAllMachines(index, boxIndex);
|
|
}
|
|
else
|
|
{
|
|
return CGarages::IsGarageEmpty(index, boxIndex);
|
|
}
|
|
}
|
|
|
|
// This uses the vehicles bounding volume in the event the player is in a vehicle.
|
|
bool CommandIsPlayerEntirelyInsideGarage(int garageHash, int playerIndex, float margin, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
CPed * pPlayer = CTheScripts::FindLocalPlayerPed(playerIndex);
|
|
if (SCRIPT_VERIFY(pPlayer, "Failed to get player, bad player index"))
|
|
{
|
|
return CGarages::IsPlayerEntirelyInsideGarage(index, pPlayer, margin, boxIndex);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// This uses the vehicles bounding volume in the event the player is in a vehicle.
|
|
bool CommandIsPlayerEntirelyOutsideGarage(int garageHash, int playerIndex, float margin, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
CPed * pPlayer = CTheScripts::FindLocalPlayerPed(playerIndex);
|
|
if (SCRIPT_VERIFY(pPlayer, "Failed to get player, bad player index"))
|
|
{
|
|
return CGarages::IsPlayerEntirelyOutsideGarage(index, pPlayer, margin, boxIndex);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// This uses the vehicles bounding volume in the event the player is in a vehicle.
|
|
bool CommandIsPlayerPartiallyInsideGarage(int garageHash, int playerIndex, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
CPed * pPlayer = CTheScripts::FindLocalPlayerPed(playerIndex);
|
|
|
|
if (SCRIPT_VERIFY(pPlayer, "Failed to get player, bad player index"))
|
|
{
|
|
return CGarages::IsPlayerPartiallyInsideGarage(index, pPlayer, boxIndex);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CommandAreEntitiesEntirelyInsideGarage(int garageHash, bool peds, bool vehs, bool objs, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
return CGarages::AreEntitiesEntirelyInsideGarage(index, peds, vehs, objs, 0.f, boxIndex);
|
|
}
|
|
|
|
bool CommandIsAnyEntityEntirelyInsideGarage(int garageHash, bool peds, bool vehs, bool objs, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
return CGarages::IsAnyEntityEntirelyInsideGarage(index, peds, vehs, objs, 0.f, boxIndex);
|
|
}
|
|
|
|
|
|
bool CommandIsObjectEntirelyInsideGarage(int garageHash, int entityIndex, float margin, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
const CEntity *pEntity = CTheScripts::GetEntityToQueryFromGUID<CEntity>(entityIndex);
|
|
if (SCRIPT_VERIFY(pEntity, "Failed to get entity, bad entity index "))
|
|
{
|
|
return CGarages::IsObjectEntirelyInsideGarage(index, pEntity, margin, boxIndex);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CommandIsObjectEntirelyOutsideGarage(int garageHash, int entityIndex, float margin, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
const CEntity *pEntity = CTheScripts::GetEntityToQueryFromGUID<CEntity>(entityIndex);
|
|
if (SCRIPT_VERIFY(pEntity, "Failed to get entity, bad entity index "))
|
|
{
|
|
return CGarages::IsObjectEntirelyOutsideGarage(index, pEntity, margin, boxIndex);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CommandIsObjectPartiallyInsideGarage(int garageHash, int entityIndex, int boxIndex)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
const CEntity *pEntity = CTheScripts::GetEntityToQueryFromGUID<CEntity>(entityIndex);
|
|
|
|
if (SCRIPT_VERIFY(pEntity, "Failed to get entity, bad entity index "))
|
|
{
|
|
return CGarages::IsObjectPartiallyInsideGarage(index, pEntity, boxIndex);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CommandClearGarage(int garageHash, bool bBroadcast)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
atArray<CEntity*> objectArray;
|
|
CGarages::FindAllObjectsInGarage(index, objectArray, true, true, true);
|
|
|
|
CGarage *pGarage = &CGarages::aGarages[index];
|
|
|
|
// Just use use box 0
|
|
CGarage::Box &box = pGarage->m_boxes[0];
|
|
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);
|
|
|
|
for (int i = 0; i < objectArray.GetCount(); ++i)
|
|
{
|
|
if (objectArray[i]->GetOwnedBy() == ENTITY_OWNEDBY_SCRIPT)
|
|
{
|
|
continue;
|
|
}
|
|
if (objectArray[i]->GetIsTypePed())
|
|
{
|
|
CPed *pPlayer = static_cast<CPed*>(objectArray[i]);
|
|
if (pPlayer->IsControlledByLocalOrNetworkPlayer())
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
if (objectArray[i]->GetIsTypeVehicle())
|
|
{
|
|
CVehicle *pVehicle = static_cast<CVehicle*>(objectArray[i]);
|
|
if (pVehicle->ContainsPlayer())
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
objectArray[i]->SetPosition(position);
|
|
}
|
|
|
|
float halfMag1 = delta1.Mag() * 0.5f;
|
|
float halfMag2 = delta2.Mag() * 0.5f;
|
|
float radius = Min(halfMag1, halfMag2);
|
|
|
|
scrVector srcVec(position);
|
|
misc_commands::CommandClearArea(srcVec, radius, true, true, true, bBroadcast);
|
|
}
|
|
|
|
void CommandClearObjectsFromGarage(int garageHash, bool vehicles, bool peds, bool objects, bool bBroadcast)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
atArray<CEntity*> objectArray;
|
|
CGarages::FindAllObjectsInGarage(index, objectArray, peds, vehicles, objects);
|
|
|
|
CGarage *pGarage = &CGarages::aGarages[index];
|
|
|
|
// Just use use box 0
|
|
CGarage::Box &box = pGarage->m_boxes[0];
|
|
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);
|
|
|
|
for (int i = 0; i < objectArray.GetCount(); ++i)
|
|
{
|
|
CEntity *pEntity = objectArray[i];
|
|
if (pEntity->GetOwnedBy() == ENTITY_OWNEDBY_SCRIPT)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (pEntity->GetIsTypePed())
|
|
{
|
|
CPed *pPlayer = static_cast<CPed*>(pEntity);
|
|
if (pPlayer->IsControlledByLocalOrNetworkPlayer())
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (pEntity->GetIsTypeVehicle())
|
|
{
|
|
CVehicle *pVehicle = static_cast<CVehicle*>(pEntity);
|
|
if (pVehicle->ContainsPlayer())
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ((vehicles && pEntity->GetIsTypeVehicle()) ||
|
|
(peds && pEntity->GetIsTypePed()) ||
|
|
(objects && pEntity->GetIsTypeObject()))
|
|
{
|
|
pEntity->SetPosition(position);
|
|
}
|
|
}
|
|
|
|
float halfMag1 = delta1.Mag() * 0.5f;
|
|
float halfMag2 = delta2.Mag() * 0.5f;
|
|
float radius = Min(halfMag1, halfMag2);
|
|
|
|
scrVector srcVec(position);
|
|
if (vehicles)
|
|
{
|
|
misc_commands::CommandClearAreaOfVehicles(srcVec, radius, true, false, false, false, bBroadcast, false, false);
|
|
}
|
|
|
|
if (peds)
|
|
{
|
|
misc_commands::CommandClearAreaOfPeds(srcVec, radius, bBroadcast);
|
|
}
|
|
|
|
if (objects)
|
|
{
|
|
s32 flags = 0;
|
|
if (bBroadcast)
|
|
{
|
|
flags |= CLEAROBJ_FLAG_BROADCAST;
|
|
}
|
|
misc_commands::CommandClearAreaOfObjects(srcVec, radius, flags);
|
|
}
|
|
}
|
|
|
|
void CommandCloseSafeHouseGarages()
|
|
{
|
|
CGarages::CloseSafeHouseGarages();
|
|
}
|
|
|
|
void CommandEnableSavingInGarage(int garageHash, bool enable)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
if (SCRIPT_VERIFY(index >= 0 && index < CGarages::GetNumGarages(), "Garage hash returned an invalid index"))
|
|
{
|
|
CGarage *pGarage = &CGarages::aGarages[index];
|
|
pGarage->Flags.bSavingVehiclesEnabled = enable;
|
|
}
|
|
}
|
|
|
|
bool CommandIsSavingEnableForGarage(int garageHash)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
if (SCRIPT_VERIFY(index >= 0 && index < CGarages::GetNumGarages(), "Garage hash returned an invalid index"))
|
|
{
|
|
CGarage *pGarage = &CGarages::aGarages[index];
|
|
return pGarage->Flags.bSavingVehiclesEnabled;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CommandDisableTidyingUp(int garageHash, bool disable)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
if (SCRIPT_VERIFY(index >= 0 && index < CGarages::GetNumGarages(), "DISABLE_TIDYING_UP_IN_GARAGE - Garage hash returned an invalid index"))
|
|
{
|
|
CGarage *pGarage = &CGarages::aGarages[index];
|
|
pGarage->Flags.bDisableTidyingUp = disable;
|
|
}
|
|
}
|
|
|
|
bool CommandIsTidyingUpDisabledForGarage(int garageHash)
|
|
{
|
|
s32 index = CGarages::FindGarageIndexFromNameHash(garageHash);
|
|
if (SCRIPT_VERIFY(index >= 0 && index < CGarages::GetNumGarages(), "IS_TIDYING_UP_DISABLED_FOR_GARAGE - Garage hash returned an invalid index"))
|
|
{
|
|
CGarage *pGarage = &CGarages::aGarages[index];
|
|
return pGarage->Flags.bDisableTidyingUp;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int CommandGetWeaponTypeFromPickupType(int pickupHash)
|
|
{
|
|
pickupHash = ConvertOldPickupTypeToHash(pickupHash);
|
|
const CPickupData* pPickupData = CPickupDataManager::GetPickupData((u32)pickupHash);
|
|
if(SCRIPT_VERIFY(pPickupData, "GET_WEAPON_TYPE_FROM_PICKUP_TYPE: pickup metadata does not exist for this pickup type."))
|
|
{
|
|
u32 numRewards = pPickupData->GetNumRewards();
|
|
for (u32 i=0; i<numRewards; i++)
|
|
{
|
|
const CPickupRewardData* pReward = pPickupData->GetReward(i);
|
|
if(pReward && pReward->GetType() == PICKUP_REWARD_TYPE_WEAPON)
|
|
{
|
|
return ((CPickupRewardWeapon*)pReward)->GetWeaponHash();
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CommandGetPickupTypeFromWeaponHash(int weaponHash)
|
|
{
|
|
const CWeaponInfo* weaponInfo = CWeaponInfoManager::GetInfo<CWeaponInfo>(weaponHash);
|
|
if(weaponInfo)
|
|
{
|
|
return weaponInfo->GetPickupHash();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
//
|
|
//
|
|
//
|
|
//
|
|
bool CommandIsPickupWeaponObjectValid(int PickupIndex)
|
|
{
|
|
const CPickup* pPickup = CTheScripts::GetEntityToModifyFromGUID<CPickup>(PickupIndex);
|
|
if (SCRIPT_VERIFY(pPickup,"GET_PICKUP_OBJECT - Pickup does not exist"))
|
|
{
|
|
if (pPickup->GetWeapon())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int CommandGetObjectTintIndex(int ObjectIndex)
|
|
{
|
|
const CObject *pObj = CTheScripts::GetEntityToQueryFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
return pObj->GetTintIndex();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void CommandSetObjectTintIndex(int ObjectIndex, int TintIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
pObj->SetTintIndex(TintIndex);
|
|
|
|
CCustomShaderEffectTint *pTintCSE = pObj->GetCseTintFromObject();
|
|
if(pTintCSE)
|
|
{
|
|
pTintCSE->SelectTintPalette((u8)TintIndex, pObj);
|
|
}
|
|
|
|
#if GTA_REPLAY
|
|
if(NetworkInterface::IsGameInProgress() && pObj->GetModelNameHash() == 0x4fcad2e0/*"apa_mp_apa_yacht"*/ && pObj->GetRelatedDummy())
|
|
{
|
|
CReplayMgr::RecordFx(CPacketSetDummyObjectTint(pObj->GetMatrix().GetCol3(), pObj->GetModelNameHash(), TintIndex, pObj->GetRelatedDummy()));
|
|
}
|
|
else if(NetworkInterface::IsGameInProgress())
|
|
{
|
|
CReplayMgr::RecordFx(CPacketSetObjectTint(TintIndex, pObj), pObj);
|
|
}
|
|
#endif // GTA_REPLAY
|
|
}
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
int CommandGetTintIndexClosestBuildingOfType(const scrVector & scrVecCentreCoors, float Radius, int ObjectModelHashKey)
|
|
{
|
|
Vector3 VecNewCoors = Vector3(scrVecCentreCoors);
|
|
|
|
s32 nOwnedByFlags = 0xFFFFFFFF;
|
|
|
|
CEntity *pClosestEntity = CObject::GetPointerToClosestMapObjectForScript(VecNewCoors.x, VecNewCoors.y, VecNewCoors.z, Radius, ObjectModelHashKey, ENTITY_TYPE_MASK_BUILDING, nOwnedByFlags);
|
|
if (pClosestEntity)
|
|
{
|
|
CBuilding *pClosestBuilding = NULL;
|
|
|
|
if(pClosestEntity->GetIsTypeBuilding())
|
|
{
|
|
pClosestBuilding = static_cast<CBuilding*>(pClosestEntity);
|
|
}
|
|
else
|
|
{
|
|
scriptAssertf(false, "%s:GET_TINT_INDEX_CLOSEST_BUILDING_OF_TYPE - grabbed object %s is not a building!",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestBuilding->GetModelName());
|
|
return -1;
|
|
}
|
|
|
|
|
|
if (pClosestBuilding)
|
|
{
|
|
return pClosestBuilding->GetTintIndex();
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static CCustomShaderEffectTint* GetCseTintFromEntity(CEntity *pEntity)
|
|
{
|
|
if( pEntity->GetDrawHandlerPtr() )
|
|
{
|
|
fwCustomShaderEffect *fwCSE = pEntity->GetDrawHandler().GetShaderEffect();
|
|
if(fwCSE && fwCSE->GetType()==CSE_TINT)
|
|
{
|
|
return static_cast<CCustomShaderEffectTint*>(fwCSE);
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
bool CommandSetTintIndexClosestBuildingOfType(const scrVector & scrVecCentreCoors, float Radius, int ObjectModelHashKey, int TintIndex)
|
|
{
|
|
Vector3 VecNewCoors = Vector3(scrVecCentreCoors);
|
|
|
|
s32 nOwnedByFlags = 0xFFFFFFFF;
|
|
|
|
CEntity *pClosestEntity = CObject::GetPointerToClosestMapObjectForScript(VecNewCoors.x, VecNewCoors.y, VecNewCoors.z, Radius, ObjectModelHashKey, ENTITY_TYPE_MASK_BUILDING, nOwnedByFlags);
|
|
if (pClosestEntity)
|
|
{
|
|
CBuilding *pClosestBuilding = NULL;
|
|
|
|
if(pClosestEntity->GetIsTypeBuilding())
|
|
{
|
|
pClosestBuilding = static_cast<CBuilding*>(pClosestEntity);
|
|
}
|
|
else
|
|
{
|
|
scriptAssertf(false, "%s:SET_TINT_INDEX_CLOSEST_BUILDING_OF_TYPE - grabbed object %s is not a building!",
|
|
CTheScripts::GetCurrentScriptNameAndProgramCounter(), pClosestBuilding->GetModelName());
|
|
return false;
|
|
}
|
|
|
|
|
|
if (pClosestBuilding)
|
|
{
|
|
pClosestBuilding->SetTintIndex(TintIndex);
|
|
|
|
CCustomShaderEffectTint *pTintCSE = GetCseTintFromEntity(pClosestBuilding);
|
|
if(pTintCSE)
|
|
{
|
|
pTintCSE->SelectTintPalette((u8)TintIndex, pClosestBuilding);
|
|
}
|
|
|
|
|
|
#if GTA_REPLAY
|
|
if(NetworkInterface::IsGameInProgress())
|
|
{
|
|
CReplayMgr::RecordFx(CPacketSetBuildingTint(VECTOR3_TO_VEC3V(VecNewCoors), Radius, ObjectModelHashKey, TintIndex, pClosestBuilding));
|
|
}
|
|
#endif // GTA_REPLAY
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
static CCustomShaderEffectProp* GetCsePropFromObject(CObject *pObj)
|
|
{
|
|
fwCustomShaderEffect *fwCSE = pObj->GetDrawHandler().GetShaderEffect();
|
|
if(fwCSE && fwCSE->GetType()==CSE_PROP)
|
|
{
|
|
return static_cast<CCustomShaderEffectProp*>(fwCSE);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int CommandGetPropTintIndex(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
CCustomShaderEffectProp *pPropCSE = GetCsePropFromObject(pObj);
|
|
if(pPropCSE)
|
|
{
|
|
return pPropCSE->GetMaxTintPalette();
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void CommandSetPropTintIndex(int ObjectIndex, int TintIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
CCustomShaderEffectProp *pPropCSE = GetCsePropFromObject(pObj);
|
|
if(pPropCSE)
|
|
{
|
|
return pPropCSE->SelectTintPalette((u8)TintIndex, pObj);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
bool CommandSetPropLightColor(int ObjectIndex, bool enable, int red, int green, int blue)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
bool bSuccess = false;
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
Color32 previousColour(255, 255, 255, 255);
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if(pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{
|
|
bSuccess = true;
|
|
|
|
pLightEntity->OverrideLightColor(enable, (u8)red, (u8)green, (u8)blue);
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
#if GTA_REPLAY
|
|
if(NetworkInterface::IsGameInProgress() && bSuccess)
|
|
{
|
|
Color32* prevColour = nullptr;
|
|
CPacketOverrideObjectLightColour::GetColourOverride(pObj->GetReplayID(), prevColour);
|
|
|
|
Color32 newColour((u8)red, (u8)green, (u8)blue, enable ? 255 : 0);
|
|
if(prevColour == nullptr || *prevColour != newColour)
|
|
{
|
|
if(prevColour)
|
|
previousColour = *prevColour;
|
|
|
|
CReplayMgr::RecordFx(CPacketOverrideObjectLightColour(previousColour, newColour), pObj);
|
|
|
|
CPacketOverrideObjectLightColour::StoreColourOverride(pObj->GetReplayID(), newColour);
|
|
|
|
replayDebugf3("Record colour override %p %d 0x%08X, %d, %d, %d, %d (%d)", pObj, ObjectIndex, pObj->GetReplayID().ToInt(), red, green, blue, enable ? 255 : 0, CPacketOverrideObjectLightColour::GetColourOverrideCount());
|
|
}
|
|
}
|
|
#endif // GTA_REPLAY
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
bool CommandIsPropLightColorOverriden(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if (pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{
|
|
// status of first child only:
|
|
return pLightEntity->IsLightColorOverriden();
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
return false;
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
//
|
|
int CommandGetPropLightColorRed(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if (pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{ // status of first child only:
|
|
Color32 col = pLightEntity->GetOverridenLightColor();
|
|
return pLightEntity->IsLightColorOverriden() ? col.GetRed() : -1;
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
return -1;
|
|
}
|
|
|
|
int CommandGetPropLightColorGreen(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if(pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{ // status of first child only:
|
|
Color32 col = pLightEntity->GetOverridenLightColor();
|
|
return pLightEntity->IsLightColorOverriden() ? col.GetGreen() : -1;
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
return -1;
|
|
}
|
|
|
|
int CommandGetPropLightColorBlue(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if(pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{ // status of first child only:
|
|
Color32 col = pLightEntity->GetOverridenLightColor();
|
|
return pLightEntity->IsLightColorOverriden() ? col.GetBlue() : -1;
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
return -1;
|
|
}
|
|
|
|
int CommandGetPropLightOrigColorRed(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if (pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{ // status of first child only:
|
|
CLightAttr* attr = pLightEntity->GetLight();
|
|
if (attr)
|
|
{
|
|
return attr->m_colour.red;
|
|
}
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
return -1;
|
|
}
|
|
|
|
int CommandGetPropLightOrigColorGreen(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if (pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{ // status of first child only:
|
|
CLightAttr* attr = pLightEntity->GetLight();
|
|
if (attr)
|
|
{
|
|
return attr->m_colour.green;
|
|
}
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
return -1;
|
|
}
|
|
|
|
int CommandGetPropLightOrigColorBlue(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
|
|
const s32 maxNumLightEntities = (s32)CLightEntity::GetPool()->GetSize();
|
|
|
|
for(s32 i=0; i<maxNumLightEntities; i++)
|
|
{
|
|
if(CLightEntity::GetPool()->GetIsUsed(i))
|
|
{
|
|
CLightEntity* pLightEntity = CLightEntity::GetPool()->GetSlot(i);
|
|
if (pLightEntity && (pLightEntity->GetParent() == pObj))
|
|
{ // status of first child only:
|
|
CLightAttr* attr = pLightEntity->GetLight();
|
|
if (attr)
|
|
{
|
|
return attr->m_colour.blue;
|
|
}
|
|
}
|
|
}
|
|
}//for(s32 i=0; i<maxNumLightEntities; i++)...
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
void CommandSetForceObjectThisFrame(const scrVector & vPos, float fRadius)
|
|
{
|
|
scriptAssertf(fRadius<=80.0f, "%s:SET_FORCE_OBJECT_THIS_FRAME - radius %.2f is too big (50m max)", CTheScripts::GetCurrentScriptNameAndProgramCounter(), fRadius);
|
|
|
|
const float fClampedRadius = Clamp(fRadius, 1.0f, 80.0f);
|
|
spdSphere forceObjSphere((Vec3V) vPos, ScalarV(fClampedRadius) );
|
|
|
|
CObjectPopulation::SetScriptForceConvertVolumeThisFrame(forceObjSphere);
|
|
}
|
|
|
|
void CommandOnlyCleanUpObjectWhenOutOfRange(int ObjectIndex)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
pObj->m_nObjectFlags.bOnlyCleanUpWhenOutOfRange = true;
|
|
}
|
|
}
|
|
|
|
int CommandDoesObjectExistWithDecorator(const char *label)
|
|
{
|
|
CObject::Pool *pool = CObject::GetPool();
|
|
|
|
if(pool)
|
|
{
|
|
atHashWithStringBank decKey(label);
|
|
|
|
s32 i = (s32) pool->GetSize();
|
|
|
|
while(i--)
|
|
{
|
|
CObject *pObject = pool->GetSlot(i);
|
|
|
|
if(pObject)
|
|
{
|
|
if(fwDecoratorExtension::ExistsOn(*pObject, decKey))
|
|
{
|
|
return CTheScripts::GetGUIDFromEntity(const_cast<CObject&>(*pObject));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL_IN_SCRIPTING_LANGUAGE;
|
|
}
|
|
|
|
void CommandSetIsVisibleInMirrors(int ObjectIndex, bool bEnable)
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if (pObj)
|
|
{
|
|
pObj->ChangeVisibilityMask(VIS_PHASE_MASK_MIRROR_REFLECTION, bEnable, false);
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectSpeedBoostAmount( int ObjectIndex, int BoostAmount )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID< CObject >( ObjectIndex );
|
|
if( pObj )
|
|
{
|
|
if( scriptVerifyf( BoostAmount > 0 && BoostAmount < 255, "%s:SET_OBJECT_SPEED_BOOST_AMOUNT - setting boost amount to an invalid value %d", CTheScripts::GetCurrentScriptNameAndProgramCounter(), BoostAmount ) )
|
|
{
|
|
pObj->SetSpeedBoost( (u8)BoostAmount );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void CommandSetObjectSpeedBoostDuration( int ObjectIndex, float BoostDuration )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID< CObject >( ObjectIndex );
|
|
if( pObj )
|
|
{
|
|
if( scriptVerifyf( BoostDuration > 0.0f && BoostDuration < 11.0f, "%s:SET_OBJECT_SPEED_BOOST_DURATION - setting boost duration to an invalid value %f", CTheScripts::GetCurrentScriptNameAndProgramCounter(), BoostDuration ) )
|
|
{
|
|
pObj->SetSpeedBoostDuration( (u8)( BoostDuration * 25.0f ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetDisableCarCollisionsWithCarParachutes( bool disableCollisions )
|
|
{
|
|
CObject::ms_bDisableCarCollisionsWithCarParachute = disableCollisions;
|
|
}
|
|
|
|
|
|
void CommandSetProjectilesShouldExplodeWhenHitting( int ObjectIndex, bool Explode )
|
|
{
|
|
CObject *pObj = CTheScripts::GetEntityToModifyFromGUID< CObject >( ObjectIndex );
|
|
if( pObj )
|
|
{
|
|
pObj->SetProjectilesShouldExplodeOnImpact( Explode );
|
|
}
|
|
}
|
|
|
|
void CommandSetDriveArticulatedJoint( int iEntityID, bool driveOpen, int jointIndex )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( SCRIPT_VERIFY( pObject, "SET_ARTICULATED_JOINT_TARGET_ANGLE - Entity is not an object" ) )
|
|
{
|
|
//if( SCRIPT_VERIFY( ( driveOpen && !pObject->IsDriveToMaxAngleEnabled() ) || ( !driveOpen ), "SET_ARTICULATED_JOINT_TARGET_ANGLE - Driving joint that is still being driven" ) )
|
|
if( ( driveOpen && !pObject->IsDriveToMaxAngleEnabled() ) || !driveOpen )
|
|
{
|
|
pObject->SetDriveToTarget( driveOpen, jointIndex );
|
|
}
|
|
}
|
|
}
|
|
|
|
void CommandSetDriveArticulatedJointWithInflictor( int iEntityID, bool driveOpen, int jointIndex, int iInflictorID )
|
|
{
|
|
CommandSetDriveArticulatedJoint( iEntityID, driveOpen, jointIndex );
|
|
CEntity* pInflictor = CTheScripts::GetEntityToModifyFromGUID<CEntity>( iInflictorID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( pObject )
|
|
{
|
|
pObject->SetDamageInflictor( pInflictor );
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectIsAPressurePlate( int iEntityID, bool isPressurePlate )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( SCRIPT_VERIFY( pObject, "SET_OBJECT_IS_A_PRESSURE_PLATE - Entity is not an object" ) )
|
|
{
|
|
pObject->SetObjectIsAPressurePlate( isPressurePlate );
|
|
}
|
|
}
|
|
|
|
bool CommandGetIsPressurePlatePressed( int iEntityID )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( SCRIPT_VERIFY( pObject, "GET_IS_PRESSURE_PLATE_PRESSED - Entity is not an object" ) )
|
|
{
|
|
return pObject->IsPressurePlatePressed();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CommandGetIsArticulatedJointAtMinAngle( int iEntityID, int jointIndex )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( SCRIPT_VERIFY( pObject, "GET_IS_ARTICULATED_JOINT_AT_MIN_ANGLE - Entity is not an object" ) )
|
|
{
|
|
return pObject->IsJointAtMinAngle( jointIndex );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CommandGetIsArticulatedJointAtMaxAngle(int iEntityID, int jointIndex)
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES);
|
|
|
|
if (SCRIPT_VERIFY(pObject, "GET_IS_ARTICULATED_JOINT_AT_MAX_ANGLE - Entity is not an object"))
|
|
{
|
|
return pObject->IsJointAtMaxAngle(jointIndex);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CommandSetWeaponImpactsApplyGreaterForce( int iEntityID, bool weaponImpactsApplyGreaterForce )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( pObject )
|
|
{
|
|
pObject->SetWeaponImpactsApplyGreaterForce( weaponImpactsApplyGreaterForce );
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectIsArticulated( int iEntityID, bool isArticulated )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( SCRIPT_VERIFY( pObject, "SET_IS_OBJECT_ARTICULATED - Entity is not an object" ) )
|
|
{
|
|
pObject->SetObjectIsArticulated( isArticulated );
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectIsBall( int iEntityID, bool isBall )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( SCRIPT_VERIFY( pObject, "SET_IS_OBJECT_BALL - Entity is not an object" ) )
|
|
{
|
|
pObject->SetObjectIsBall( isBall );
|
|
}
|
|
}
|
|
|
|
void CommandSetObjectPopsTyres( int iEntityID, bool popsTyres )
|
|
{
|
|
CObject *pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>( iEntityID, CTheScripts::GUID_ASSERT_FLAGS_INCLUDE_CLONES );
|
|
|
|
if( SCRIPT_VERIFY( pObject, "SET_OBJECT_POPS_TYRES - Entity is not an object" ) )
|
|
{
|
|
pObject->m_nObjectFlags.bPopTires = popsTyres;
|
|
}
|
|
}
|
|
|
|
|
|
void CommandSetObjectAlbedoFlag(int ObjectIndex, bool enable)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if(pObject)
|
|
{
|
|
pObject->SetIsAlbedoAlpha(enable);
|
|
}
|
|
}
|
|
|
|
bool CommandGetObjectAlbedoFlag(int ObjectIndex)
|
|
{
|
|
CObject* pObject = CTheScripts::GetEntityToModifyFromGUID<CObject>(ObjectIndex);
|
|
if(pObject)
|
|
{
|
|
return pObject->GetIsAlbedoAlpha();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CommandEnableGlobalAlbedoObjectsSupport(bool enable)
|
|
{
|
|
CObjectPopulation::EnableCObjectsAlbedoSupport(enable);
|
|
}
|
|
|
|
|
|
|
|
void SetupScriptCommands()
|
|
{
|
|
SCR_REGISTER_SECURE(CREATE_OBJECT,0x0e536d72ab30f4c8, CommandCreateObject );
|
|
SCR_REGISTER_SECURE(CREATE_OBJECT_NO_OFFSET,0x0a7322c6d0e1a985, CommandCreateObjectNoOffset );
|
|
SCR_REGISTER_SECURE(DELETE_OBJECT,0x4bda5afd88c085eb, CommandDeleteObject );
|
|
SCR_REGISTER_SECURE(PLACE_OBJECT_ON_GROUND_PROPERLY,0x82af23f360c69cae, CommandPlaceObjectOnGroundProperly );
|
|
SCR_REGISTER_SECURE(PLACE_OBJECT_ON_GROUND_OR_OBJECT_PROPERLY,0xe6a4c4b2e8de36d3, CommandPlaceObjectOnGroundOrObjectProperly );
|
|
SCR_REGISTER_SECURE(ROTATE_OBJECT,0x3f35e3308bda6748, CommandRotateObject );
|
|
SCR_REGISTER_SECURE(SLIDE_OBJECT,0x4a84ec87916ef892, CommandSlideObject );
|
|
SCR_REGISTER_SECURE(SET_OBJECT_TARGETTABLE,0x6486d097e5c691f3, CommandSetObjectTargettable );
|
|
SCR_REGISTER_SECURE(SET_OBJECT_FORCE_VEHICLES_TO_AVOID,0x0321bbb2a2b3b1ed, CommandSetObjectForceVehiclesToAvoid );
|
|
SCR_REGISTER_SECURE(GET_CLOSEST_OBJECT_OF_TYPE,0x87a467676bdf8c35, CommandGetClosestObjectOfType );
|
|
SCR_REGISTER_SECURE(HAS_OBJECT_BEEN_BROKEN,0xadebc1d44fe55f78, CommandHasObjectBeenBroken );
|
|
SCR_REGISTER_SECURE(HAS_CLOSEST_OBJECT_OF_TYPE_BEEN_BROKEN,0x438657bc68985918, CommandHasClosestObjectOfTypeBeenBroken );
|
|
SCR_REGISTER_SECURE(HAS_CLOSEST_OBJECT_OF_TYPE_BEEN_COMPLETELY_DESTROYED,0xfa14247da5d930c6, CommandHasClosestObjectOfTypeBeenCompletelyDestroyed);
|
|
SCR_REGISTER_SECURE(GET_HAS_OBJECT_BEEN_COMPLETELY_DESTROYED,0x1bf1f6d9dc221b91, CommandGetHasObjectBeenCompletelyDestroyed);
|
|
SCR_REGISTER_SECURE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS,0x6db7fbd602c51670, CommandGetOffsetFromCoordAndHeadingInWorldCoords);
|
|
SCR_REGISTER_UNUSED(FREEZE_POSITION_OF_CLOSEST_OBJECT_OF_TYPE,0xbc22d08e20303367, CommandFreezePositionOfClosestObjectOfType );
|
|
SCR_REGISTER_SECURE(GET_COORDS_AND_ROTATION_OF_CLOSEST_OBJECT_OF_TYPE,0x5fe5dad7c292ebe5, CommandGetCoordsAndRotationOfClosestObjectOfType);
|
|
SCR_REGISTER_SECURE(SET_STATE_OF_CLOSEST_DOOR_OF_TYPE,0x798e4bba7a3c56ae, CommandSetStateOfClosestDoorOfType );
|
|
SCR_REGISTER_SECURE(GET_STATE_OF_CLOSEST_DOOR_OF_TYPE,0xd25fb7e1030e5e2d, CommandGetStateOfClosestDoorOfType );
|
|
SCR_REGISTER_SECURE(SET_LOCKED_UNSTREAMED_IN_DOOR_OF_TYPE,0x82ef7f252a48dc41, CommandSetLockedUnstreamedInDoorOfType );
|
|
SCR_REGISTER_SECURE(PLAY_OBJECT_AUTO_START_ANIM,0xc225c3d9cc954480, CommandPlayObjectAutoStartAnim);
|
|
|
|
SCR_REGISTER_SECURE(ADD_DOOR_TO_SYSTEM,0x5dd86ac785d8e188, CommandAddDoorToSystem );
|
|
SCR_REGISTER_SECURE(REMOVE_DOOR_FROM_SYSTEM,0xa5bd780899e2d5f0, CommandRemoveDoorFromSystem );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_SET_DOOR_STATE,0x7e15597aa5f53f9a, CommandDoorSystemSetState );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_GET_DOOR_STATE,0xa570d693c4a2b421, CommandDoorSystemGetState );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_GET_DOOR_PENDING_STATE,0xdc62e683fb337ec3, CommandDoorSystemGetPendingState );
|
|
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_SET_AUTOMATIC_RATE,0x1f0b6d1966e55ddb, CommandDoorSystemSetAutomaticRate );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_SET_AUTOMATIC_DISTANCE,0x32dbceb580393767, CommandDoorSystemSetAutomaticDistance );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_SET_OPEN_RATIO,0x1b3e1454bd86fce6, CommandDoorSystemSetOpenRatio );
|
|
|
|
SCR_REGISTER_UNUSED(DOOR_SYSTEM_GET_AUTOMATIC_RATE,0xb3eef85759c0825d, CommandDoorSystemGetAutomaticRate );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_GET_AUTOMATIC_DISTANCE,0x478b4c9fd32a6ef9, CommandDoorSystemGetAutomaticDistance );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_GET_OPEN_RATIO,0xc4336736b30c9df5, CommandDoorSystemGetOpenRatio );
|
|
|
|
SCR_REGISTER_UNUSED(DOOR_SYSTEM_GET_IS_SPRING_REMOVED,0xc1a5bd435907950f, CommandDoorSystemGetUnsprung );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_SET_SPRING_REMOVED,0xf9d6c7efa350cf1d, CommandDoorSystemSetUnsprung );
|
|
|
|
SCR_REGISTER_UNUSED(DOOR_SYSTEM_GET_IS_HOLDING_OPEN,0x0b3c3f3cb7039f8f, CommandDoorSystemGetHoldOpen );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_SET_HOLD_OPEN,0x240efbc99404843a, CommandDoorSystemSetHoldOpen );
|
|
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_SET_DOOR_OPEN_FOR_RACES,0xeeff17c042a8cb2c, CommandDoorSystemSetOpenForRaces );
|
|
SCR_REGISTER_UNUSED(DOOR_SYSTEM_GET_DOOR_OPEN_FOR_RACES,0xc00251d702757ea3, CommandDoorSystemGetOpenForRaces );
|
|
|
|
SCR_REGISTER_UNUSED(SET_DOOR_OBJECT_ALWAYS_PUSH_VEHICLES,0xac05f02664b3fb07, CommandDoorSetAlwaysPushVehicles );
|
|
|
|
SCR_REGISTER_SECURE(IS_DOOR_REGISTERED_WITH_SYSTEM,0xec32121f2e3875c8, CommandIsDoorRegisteredWithSystem );
|
|
SCR_REGISTER_SECURE(IS_DOOR_CLOSED,0xbe1365fc512b1f58, CommandIsDoorClosed );
|
|
SCR_REGISTER_UNUSED(IS_DOOR_FULLY_OPEN,0xdc06ae18038d670f, CommandIsDoorFullyOpen );
|
|
|
|
SCR_REGISTER_SECURE(OPEN_ALL_BARRIERS_FOR_RACE,0x25dc8c12248c3966, CommandOpenAllBarriersForRace );
|
|
SCR_REGISTER_SECURE(CLOSE_ALL_BARRIERS_FOR_RACE,0x711d6d89f98ade64, CommandCloseAllBarriersOpenedForRace );
|
|
|
|
SCR_REGISTER_UNUSED(DOOR_SET_ALWAYS_PUSH,0x480500aa9e8b631f, CommandDoorSetAlwaysPush );
|
|
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_GET_IS_PHYSICS_LOADED,0x163a0b16532bf618, CommandDoorSystemGetIsPhysicsLoaded );
|
|
SCR_REGISTER_SECURE(DOOR_SYSTEM_FIND_EXISTING_DOOR,0x733969cd24ac2dd3, CommandDoorSystemFindExistingDoor );
|
|
|
|
SCR_REGISTER_SECURE(IS_GARAGE_EMPTY,0x627ec3ebc804e164, CommandIsGarageEmpty );
|
|
SCR_REGISTER_SECURE(IS_PLAYER_ENTIRELY_INSIDE_GARAGE,0x3bbe1aefbffe5646, CommandIsPlayerEntirelyInsideGarage );
|
|
SCR_REGISTER_UNUSED(IS_PLAYER_ENTIRELY_OUTSIDE_GARAGE,0xa5e25f9b71a87908, CommandIsPlayerEntirelyOutsideGarage );
|
|
SCR_REGISTER_SECURE(IS_PLAYER_PARTIALLY_INSIDE_GARAGE,0xf2706324c8ce4795, CommandIsPlayerPartiallyInsideGarage );
|
|
SCR_REGISTER_SECURE(ARE_ENTITIES_ENTIRELY_INSIDE_GARAGE,0x8f65a904fbec6771, CommandAreEntitiesEntirelyInsideGarage );
|
|
SCR_REGISTER_SECURE(IS_ANY_ENTITY_ENTIRELY_INSIDE_GARAGE,0x57550d67d90afdd6, CommandIsAnyEntityEntirelyInsideGarage );
|
|
|
|
SCR_REGISTER_SECURE(IS_OBJECT_ENTIRELY_INSIDE_GARAGE,0x26b6fbd29e6b5df6, CommandIsObjectEntirelyInsideGarage );
|
|
SCR_REGISTER_UNUSED(IS_OBJECT_ENTIRELY_OUTSIDE_GARAGE,0xd8b483e51cad8cfc, CommandIsObjectEntirelyOutsideGarage );
|
|
SCR_REGISTER_SECURE(IS_OBJECT_PARTIALLY_INSIDE_GARAGE,0xe251d6fac6328abf, CommandIsObjectPartiallyInsideGarage );
|
|
|
|
SCR_REGISTER_SECURE(CLEAR_GARAGE,0xd3fd4677db79e1d1, CommandClearGarage );
|
|
SCR_REGISTER_SECURE(CLEAR_OBJECTS_INSIDE_GARAGE,0x22676f5a35047ca3, CommandClearObjectsFromGarage );
|
|
|
|
SCR_REGISTER_SECURE(DISABLE_TIDYING_UP_IN_GARAGE,0xeaec749a161c79e4, CommandDisableTidyingUp );
|
|
SCR_REGISTER_UNUSED(IS_TIDYING_UP_DISABLED_FOR_GARAGE,0xeb1f9fd79915129b, CommandIsTidyingUpDisabledForGarage );
|
|
SCR_REGISTER_UNUSED(IS_SAVING_ENABLED_FOR_GARAGE,0xeb21b94a7160cc61, CommandIsSavingEnableForGarage );
|
|
SCR_REGISTER_SECURE(ENABLE_SAVING_IN_GARAGE,0x334505b911993b1e, CommandEnableSavingInGarage );
|
|
SCR_REGISTER_SECURE(CLOSE_SAFEHOUSE_GARAGES,0xb2443d8f4dba9077, CommandCloseSafeHouseGarages );
|
|
|
|
SCR_REGISTER_SECURE(DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS,0x574e2a23f0f76e35, CommandDoesObjectOfTypeExistAtCoords );
|
|
SCR_REGISTER_SECURE(IS_POINT_IN_ANGLED_AREA,0x5f8653e60ed2288e, CommandIsPointInAngledArea );
|
|
SCR_REGISTER_UNUSED(SET_OBJECT_AS_STEALABLE,0xcd45c0d75d9bf726, CommandSetObjectAsStealable );
|
|
SCR_REGISTER_UNUSED(HAS_OBJECT_BEEN_UPROOTED,0x65bc987a38ca0272, CommandHasObjectBeenUprooted );
|
|
SCR_REGISTER_UNUSED(SET_NEAREST_BUILDING_ANIM_RATE,0xe5f39e67f337bf33, CommandSetNearestBuildingAnimRate);
|
|
SCR_REGISTER_UNUSED(GET_NEAREST_BUILDING_ANIM_RATE,0xdd6b1ab4b4acae7e, CommandGetNearestBuildingAnimRate);
|
|
SCR_REGISTER_UNUSED(SET_NEAREST_BUILDING_ANIM_PHASE,0x17818d14b29dc55a, CommandSetNearestBuildingAnimPhase);
|
|
SCR_REGISTER_UNUSED(GET_NEAREST_BUILDING_ANIM_PHASE,0x371743df03ed7aee, CommandGetNearestBuildingAnimPhase);
|
|
SCR_REGISTER_SECURE(SET_OBJECT_ALLOW_LOW_LOD_BUOYANCY,0x225f199ba06b3d82, CommandSetObjectAllowLowLodBuoyancy);
|
|
SCR_REGISTER_SECURE(SET_OBJECT_PHYSICS_PARAMS,0xcc2383c749571bd1, CommandSetObjectPhysicsParams);
|
|
SCR_REGISTER_SECURE(GET_OBJECT_FRAGMENT_DAMAGE_HEALTH,0x13ac33b32a4f4e11, CommandGetObjectFragmentDamageHealth);
|
|
SCR_REGISTER_SECURE(SET_ACTIVATE_OBJECT_PHYSICS_AS_SOON_AS_IT_IS_UNFROZEN,0xe987efb3b3fab187, CommandSetActivateObjectPhysicsAsSoonAsItIsUnfrozen);
|
|
SCR_REGISTER_UNUSED(SET_ARROW_ABOVE_BLIPPED_PICKUPS, 0xede49b32, CommandSetArrowAboveBlippedPickups);
|
|
SCR_REGISTER_SECURE(IS_ANY_OBJECT_NEAR_POINT,0x2d3cddf3fe35fca6, CommandIsAnyObjectNearPoint);
|
|
SCR_REGISTER_SECURE(IS_OBJECT_NEAR_POINT,0x6870f49b9937b9d1, CommandIsObjectNearPoint);
|
|
SCR_REGISTER_UNUSED(REQUEST_OBJECT_HIGH_DETAIL_MODEL,0x3b03a53d753d3bf9, CommandRequestObjectHighDetailModel);
|
|
SCR_REGISTER_SECURE(REMOVE_OBJECT_HIGH_DETAIL_MODEL,0x5f012c14ed0c0c36, CommandRemoveObjectHighDetailModel);
|
|
|
|
SCR_REGISTER_SECURE(BREAK_OBJECT_FRAGMENT_CHILD,0xb35d04a52bd51f16, CommandObjectFragmentBreakChild);
|
|
SCR_REGISTER_SECURE(DAMAGE_OBJECT_FRAGMENT_CHILD,0xae6555cd897a035d, CommandObjectFragmentDamageChild);
|
|
SCR_REGISTER_SECURE(FIX_OBJECT_FRAGMENT,0xf4da4bbc6876e774, CommandObjectFragmentFix);
|
|
|
|
SCR_REGISTER_SECURE(TRACK_OBJECT_VISIBILITY,0x6e740265db1f6ea1, CommandTrackObjectVisibility);
|
|
SCR_REGISTER_SECURE(IS_OBJECT_VISIBLE,0x3e04de565f9095b8, CommandIsObjectVisible);
|
|
|
|
SCR_REGISTER_SECURE(SET_OBJECT_IS_SPECIAL_GOLFBALL,0x04a0ccec1611db8a, CommandSetObjectIsSpecialGolfBall);
|
|
SCR_REGISTER_SECURE(SET_OBJECT_TAKES_DAMAGE_FROM_COLLIDING_WITH_BUILDINGS,0x2c08bd44740dbbfe, CommandSetTakesDamageFromCollidingWithBuildings);
|
|
SCR_REGISTER_SECURE(ALLOW_DAMAGE_EVENTS_FOR_NON_NETWORKED_OBJECTS,0xd9b751e2b8db8914, CommandAllowDamageEventsForNonNetworkedObjects);
|
|
|
|
SCR_REGISTER_SECURE(SET_CUTSCENES_WEAPON_FLASHLIGHT_ON_THIS_FRAME,0x0e4a297378aba0e1, CommandSetCutscenesWeaponFlashlightOnThisFrame);
|
|
|
|
// Rayfire commands
|
|
SCR_REGISTER_SECURE(GET_RAYFIRE_MAP_OBJECT,0x6b3ee0ca145e8488, CommandGetCompositeEntityAt);
|
|
SCR_REGISTER_SECURE(SET_STATE_OF_RAYFIRE_MAP_OBJECT,0x288f018bfd3d51ed, CommandSetCompositeEntityState);
|
|
SCR_REGISTER_SECURE(GET_STATE_OF_RAYFIRE_MAP_OBJECT,0xd17b3afa40998041, CommandGetCompositeEntityState);
|
|
SCR_REGISTER_UNUSED(PAUSE_RAYFIRE_MAP_OBJECT_AT_PHASE,0x29874e719d2e59e7, CommandPauseCompositeEntityAtPhase);
|
|
SCR_REGISTER_SECURE(DOES_RAYFIRE_MAP_OBJECT_EXIST,0xf0254dadd9d91fb8, CommandDoesRayFireMapObjectExist);
|
|
SCR_REGISTER_SECURE(GET_RAYFIRE_MAP_OBJECT_ANIM_PHASE,0xb0431da36e2aa134, CommandGetCompEntityAnimationPhase);
|
|
// pickup commands
|
|
SCR_REGISTER_SECURE(CREATE_PICKUP,0x1cd347d2bd906560, CommandCreatePickup );
|
|
SCR_REGISTER_SECURE(CREATE_PICKUP_ROTATE,0x1ee09f99fef19daf, CommandCreatePickupRotate );
|
|
SCR_REGISTER_SECURE(FORCE_PICKUP_ROTATE_FACE_UP,0x520df2d45632ce77, CommandForcePickupRotateFaceUp );
|
|
SCR_REGISTER_SECURE(SET_CUSTOM_PICKUP_WEAPON_HASH,0x764344c3b3372eda, CommandSetCustomPickupWeaponHash );
|
|
SCR_REGISTER_SECURE(CREATE_AMBIENT_PICKUP,0xb765858a7a410073, CommandCreateAmbientPickup );
|
|
SCR_REGISTER_SECURE(CREATE_NON_NETWORKED_AMBIENT_PICKUP,0xc9b8424fe1c703cf, CommandCreateNonNetworkedAmbientPickup );
|
|
SCR_REGISTER_UNUSED(BLOCK_PLAYERS_FOR_PICKUP,0x895af49b57426c0f, CommandBlockPlayersForPickup );
|
|
SCR_REGISTER_SECURE(BLOCK_PLAYERS_FOR_AMBIENT_PICKUP,0x03f97d082c4210a5, CommandBlockPlayersForAmbientPickup );
|
|
SCR_REGISTER_SECURE(CREATE_PORTABLE_PICKUP,0x9431d28bfc30340b, CommandCreatePortablePickup );
|
|
SCR_REGISTER_SECURE(CREATE_NON_NETWORKED_PORTABLE_PICKUP,0xa22803867109bfb0, CommandCreateNonNetworkedPortablePickup );
|
|
SCR_REGISTER_SECURE(ATTACH_PORTABLE_PICKUP_TO_PED,0xa4dc05dfb08a8957, CommandAttachPortablePickupToPed );
|
|
SCR_REGISTER_SECURE(DETACH_PORTABLE_PICKUP_FROM_PED,0x1c9488ec3f23b199, CommandDetachPortablePickupFromPed );
|
|
SCR_REGISTER_SECURE(FORCE_PORTABLE_PICKUP_LAST_ACCESSIBLE_POSITION_SETTING, 0x5CE2E45A5CE2E45A, CommandForcePortablePickupLastAccessiblePositionSetting);
|
|
SCR_REGISTER_SECURE(HIDE_PORTABLE_PICKUP_WHEN_DETACHED,0xd649c4fd90f64861, CommandHidePortablePickupWhenDetached );
|
|
SCR_REGISTER_SECURE(SET_MAX_NUM_PORTABLE_PICKUPS_CARRIED_BY_PLAYER,0x9af1d0c5f270c910, CommandSetMaxNumPortablePickupsCarriedByPlayer);
|
|
SCR_REGISTER_SECURE(SET_LOCAL_PLAYER_CAN_COLLECT_PORTABLE_PICKUPS,0x91fbfe715b78280c, CommandSetLocalPlayerCanCollectPortablePickups);
|
|
SCR_REGISTER_SECURE(GET_SAFE_PICKUP_COORDS,0x7f65c587e17def5d, CommandGetSafePickupCoords );
|
|
SCR_REGISTER_SECURE(ADD_EXTENDED_PICKUP_PROBE_AREA,0x28ee006afec511d9, CommandAddExtendedPickupProbeArea );
|
|
SCR_REGISTER_SECURE(CLEAR_EXTENDED_PICKUP_PROBE_AREAS,0x7a888ab940b876e8, CommandClearExtendedPickupProbeAreas );
|
|
SCR_REGISTER_SECURE(GET_PICKUP_COORDS,0x70453f7df40780a5, CommandGetPickupCoords );
|
|
SCR_REGISTER_SECURE(SUPPRESS_PICKUP_SOUND_FOR_PICKUP,0xb409e96217e8aa92, CommandSuppressPickupSoundForPickup );
|
|
SCR_REGISTER_SECURE(REMOVE_ALL_PICKUPS_OF_TYPE,0xf5341a080595c3f3, CommandRemoveAllPickupsOfType );
|
|
SCR_REGISTER_UNUSED(GET_NUMBER_OF_PICKUPS_OF_TYPE,0xb54b23d6eafb5fcf, CommandGetNumberOfPickupsOfType );
|
|
SCR_REGISTER_SECURE(HAS_PICKUP_BEEN_COLLECTED,0x803592456ae579b3, CommandHasPickupBeenCollected );
|
|
SCR_REGISTER_SECURE(REMOVE_PICKUP,0x451f33099166532a, CommandRemovePickup );
|
|
SCR_REGISTER_SECURE(CREATE_MONEY_PICKUPS,0xae315b17ac08c2a9, CommandCreateMoneyPickups );
|
|
SCR_REGISTER_UNUSED(SET_PLAYERS_DROP_MONEY_IN_NETWORK_GAME, 0x806204b, CommandSetPlayersDropMoneyInNetworkGame );
|
|
SCR_REGISTER_SECURE(DOES_PICKUP_EXIST,0x2791155fb0769fe5, CommandDoesPickupExist );
|
|
SCR_REGISTER_SECURE(DOES_PICKUP_OBJECT_EXIST,0x5f0e7de3bfa7690c, CommandDoesPickupObjectExist );
|
|
SCR_REGISTER_SECURE(GET_PICKUP_OBJECT,0x7af1def5f183c1a6, CommandGetPickupObject );
|
|
SCR_REGISTER_SECURE(IS_OBJECT_A_PICKUP,0xccebb0c0198fecdb, CommandIsObjectAPickup );
|
|
SCR_REGISTER_SECURE(IS_OBJECT_A_PORTABLE_PICKUP,0x9f781807386ac867, CommandIsObjectAPortablePickup );
|
|
SCR_REGISTER_SECURE(DOES_PICKUP_OF_TYPE_EXIST_IN_AREA,0xe4e0f69f436c8ff8, CommandDoesPickupOfTypeExistInArea );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_REGENERATION_TIME,0x69df462e3146f76e, CommandSetPickupRegenerationTime );
|
|
SCR_REGISTER_SECURE(FORCE_PICKUP_REGENERATE,0x482dcf58b0c559a4, CommandForcePickupRegenerate );
|
|
SCR_REGISTER_SECURE(SET_PLAYER_PERMITTED_TO_COLLECT_PICKUPS_OF_TYPE,0xcbd9f5754fd640bf, CommandSetPlayerPermittedToCollectPickupsOfType);
|
|
SCR_REGISTER_SECURE(SET_LOCAL_PLAYER_PERMITTED_TO_COLLECT_PICKUPS_WITH_MODEL,0xd985cd4e4d28a723, CommandSetLocalPlayerPermittedToCollectPickupsWithModel);
|
|
SCR_REGISTER_SECURE(ALLOW_ALL_PLAYERS_TO_COLLECT_PICKUPS_OF_TYPE,0xc4f1303f19df6af2, CommandAllowAllPlayersToCollectPickupsOfType );
|
|
SCR_REGISTER_UNUSED(SET_TEAM_PICKUP,0x0c480c11c7e0c37a, CommandSetTeamPickup );
|
|
SCR_REGISTER_SECURE(SET_TEAM_PICKUP_OBJECT,0x0548bdefcaa1caa7, CommandSetTeamPickupObject );
|
|
SCR_REGISTER_SECURE(PREVENT_COLLECTION_OF_PORTABLE_PICKUP,0x8175b06ed630a82a, CommandPreventCollectionOfPortablePickup );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_OBJECT_GLOW_WHEN_UNCOLLECTABLE,0x0e1b3b43a16940eb, CommandSetPickupObjectGlowWhenUncollectable );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_GLOW_OFFSET,0x6f57da45338c5293, CommandSetPickupGlowOffset );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_OBJECT_GLOW_OFFSET,0x1092ed0cc7e5a2f5, CommandSetPickupObjectGlowOffset );
|
|
SCR_REGISTER_UNUSED(SET_PICKUP_GLOW_IN_SAME_TEAM,0x269098405297dfe9, CommandSetPickupGlowForSameTeam );
|
|
SCR_REGISTER_UNUSED(SET_PICKUP_OBJECT_GLOW_IN_SAME_TEAM,0x1cedd008a678bd02, CommandSetPickupObjectGlowForSameTeam );
|
|
SCR_REGISTER_SECURE(SET_OBJECT_GLOW_IN_SAME_TEAM,0xc10f6115159d2b04, CommandSetObjectGlowForSameTeam );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_OBJECT_ARROW_MARKER,0xfd3eb69ea4ce479b, CommandSetPickupObjectArrowMarker );
|
|
SCR_REGISTER_SECURE(ALLOW_PICKUP_ARROW_MARKER_WHEN_UNCOLLECTABLE,0xd9b42564a7d9daa8, CommandAllowPickupObjectArrowMarkerWhenUncollectable);
|
|
SCR_REGISTER_SECURE(GET_DEFAULT_AMMO_FOR_WEAPON_PICKUP,0x675e742c60ddd638, CommandGetDefaultAmmoForWeaponPickup );
|
|
SCR_REGISTER_UNUSED(SET_VEHICLE_WEAPON_PICKUPS_SHARED_BY_PASSENGERS,0x41923cbe924491d9, CommandSetVehicleWeaponPickupsSharedByPassengers);
|
|
SCR_REGISTER_SECURE(SET_PICKUP_GENERATION_RANGE_MULTIPLIER,0x296fb914127b2d58, CommandSetPickupGenerationRangeMultiplier );
|
|
SCR_REGISTER_SECURE(GET_PICKUP_GENERATION_RANGE_MULTIPLIER,0xea9410ebed10ae7c, CommandGetPickupGenerationRangeMultiplier );
|
|
SCR_REGISTER_SECURE(SET_ONLY_ALLOW_AMMO_COLLECTION_WHEN_LOW,0x79c07e0ee199af10, CommandSetOnlyAllowAmmoCollectionWhenLow );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_UNCOLLECTABLE,0xac74e3ca074d8dbd, CommandSetPickupUncollectable );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_TRANSPARENT_WHEN_UNCOLLECTABLE,0xdd5baaae5696f80d, CommandSetPickupTransparentWhenUncollectable );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_HIDDEN_WHEN_UNCOLLECTABLE,0xa46cb4ea8156117b, CommandSetPickupHiddenWhenUncollectable );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_OBJECT_TRANSPARENT_WHEN_UNCOLLECTABLE,0x678cc86c4633cc3f, CommandSetPickupObjectTransparentWhenUncollectable);
|
|
SCR_REGISTER_SECURE(SET_PICKUP_OBJECT_ALPHA_WHEN_TRANSPARENT,0x6155572d912b46d6, CommandSetPickupObjectAlphaWhenTransparent );
|
|
SCR_REGISTER_SECURE(SET_PORTABLE_PICKUP_PERSIST,0x43da905252ee4ca1, CommandSetPortablePickupPersist );
|
|
SCR_REGISTER_SECURE(ALLOW_PORTABLE_PICKUP_TO_MIGRATE_TO_NON_PARTICIPANTS,0x41db71dce7894fab, CommandAllowPortablePickupToMigrateToNonParticipants);
|
|
SCR_REGISTER_SECURE(FORCE_ACTIVATE_PHYSICS_ON_UNFIXED_PICKUP,0x189ab741d56f49b9, CommandForceActivatePhysicsOnUnfixedPickup ); // Are you sure this is what you want? Not FORCE_ACTIVATE_PHYSICS_ON_DROPPED_PICKUP_NEAR_SUBMARINE?
|
|
SCR_REGISTER_UNUSED(FORCE_ACTIVATE_PHYSICS_ON_DROPPED_PICKUP_NEAR_SUBMARINE,0xf46083d431705b1c,CommandForceActivatePhysicsOnDroppedPickupNearSubmarine);
|
|
SCR_REGISTER_SECURE(ALLOW_PICKUP_BY_NONE_PARTICIPANT,0xc6e2d6b7217f48ac, CommandAllowPickupByNonParticipant );
|
|
|
|
SCR_REGISTER_UNUSED(IS_PORTABLE_PICKUP_CUSTOM_COLLIDER_READY,0x0a303c7e33325097, CommandIsPortablePickupCustomColliderReady );
|
|
SCR_REGISTER_UNUSED(IS_PICKUP_REWARD_TYPE_SUPPRESSED,0xba9733cfcaafa2dc, CommandIsPickupRewardTypeSuppressed );
|
|
SCR_REGISTER_SECURE(SUPPRESS_PICKUP_REWARD_TYPE,0xdef665962974b74c, CommandSuppressPickupRewardType );
|
|
SCR_REGISTER_SECURE(CLEAR_ALL_PICKUP_REWARD_TYPE_SUPPRESSION,0x402458806232a271, CommandClearAllPickupRewardTypeSuppression );
|
|
SCR_REGISTER_SECURE(CLEAR_PICKUP_REWARD_TYPE_SUPPRESSION,0x261c0495ce1149be, CommandClearPickupRewardTypeSuppression );
|
|
|
|
SCR_REGISTER_SECURE(RENDER_FAKE_PICKUP_GLOW,0x8c6bd716fdd7dfb2, CommandRenderFakePickup );
|
|
|
|
SCR_REGISTER_SECURE(SET_PICKUP_OBJECT_COLLECTABLE_IN_VEHICLE,0x07106eb9ee13466d, CommandSetPickupObjectCollectableInVehicle );
|
|
SCR_REGISTER_SECURE(SET_PICKUP_TRACK_DAMAGE_EVENTS,0xfd2d2d41983bb472, CommandSetPickupTrackDamageEvents );
|
|
|
|
// entity flag commands
|
|
SCR_REGISTER_SECURE(SET_ENTITY_FLAG_SUPPRESS_SHADOW,0xb43a82419553a1e8, CommandSetEntityFlag_SUPPRESS_SHADOW );
|
|
SCR_REGISTER_SECURE(SET_ENTITY_FLAG_RENDER_SMALL_SHADOW,0x01a9c9579974823f, CommandSetEntityFlag_RENDER_SMALL_SHADOW );
|
|
|
|
SCR_REGISTER_SECURE(GET_WEAPON_TYPE_FROM_PICKUP_TYPE,0xc6b776ed315b2193, CommandGetWeaponTypeFromPickupType );
|
|
SCR_REGISTER_SECURE(GET_PICKUP_TYPE_FROM_WEAPON_HASH,0xfc53f42ae5bd9601, CommandGetPickupTypeFromWeaponHash );
|
|
SCR_REGISTER_SECURE(IS_PICKUP_WEAPON_OBJECT_VALID,0xa64dbd522133c8f1, CommandIsPickupWeaponObjectValid );
|
|
|
|
SCR_REGISTER_SECURE(GET_OBJECT_TINT_INDEX,0x873082e7f40db44c, CommandGetObjectTintIndex );
|
|
SCR_REGISTER_SECURE(SET_OBJECT_TINT_INDEX,0x71b42d724f2db164, CommandSetObjectTintIndex );
|
|
SCR_REGISTER_UNUSED(GET_TINT_INDEX_CLOSEST_BUILDING_OF_TYPE,0x860f1ceecefadac0, CommandGetTintIndexClosestBuildingOfType );
|
|
SCR_REGISTER_SECURE(SET_TINT_INDEX_CLOSEST_BUILDING_OF_TYPE,0xa56ad7cec1ae4c83, CommandSetTintIndexClosestBuildingOfType );
|
|
SCR_REGISTER_UNUSED(GET_PROP_TINT_INDEX,0xd2647cb2bf6f11c0, CommandGetPropTintIndex );
|
|
SCR_REGISTER_SECURE(SET_PROP_TINT_INDEX,0x5352da2e8f114fa9, CommandSetPropTintIndex );
|
|
|
|
SCR_REGISTER_SECURE(SET_PROP_LIGHT_COLOR,0x0aeba112bfb0eeb0, CommandSetPropLightColor);
|
|
SCR_REGISTER_SECURE(IS_PROP_LIGHT_OVERRIDEN,0x384da7361ab033f6, CommandIsPropLightColorOverriden);
|
|
SCR_REGISTER_UNUSED(GET_PROP_LIGHT_COLOR_RED,0x0cf5873c6c5099f2, CommandGetPropLightColorRed);
|
|
SCR_REGISTER_UNUSED(GET_PROP_LIGHT_COLOR_GREEN,0x11311794f44f4271, CommandGetPropLightColorGreen);
|
|
SCR_REGISTER_UNUSED(GET_PROP_LIGHT_COLOR_BLUE,0x7543963afdb844f4, CommandGetPropLightColorBlue);
|
|
SCR_REGISTER_UNUSED(GET_PROP_LIGHT_ORIG_COLOR_RED,0x54a58e7404dec833, CommandGetPropLightOrigColorRed);
|
|
SCR_REGISTER_UNUSED(GET_PROP_LIGHT_ORIG_COLOR_GREEN,0x7ab3d3e47cf58566, CommandGetPropLightOrigColorGreen);
|
|
SCR_REGISTER_UNUSED(GET_PROP_LIGHT_ORIG_COLOR_BLUE,0xb4f12b45661b34b6, CommandGetPropLightOrigColorBlue);
|
|
|
|
|
|
SCR_REGISTER_SECURE(SET_OBJECT_IS_VISIBLE_IN_MIRRORS,0x9bceec68518a0848, CommandSetIsVisibleInMirrors );
|
|
|
|
SCR_REGISTER_SECURE(SET_OBJECT_SPEED_BOOST_AMOUNT,0xe67d071d390bd9d9, CommandSetObjectSpeedBoostAmount );
|
|
SCR_REGISTER_SECURE(SET_OBJECT_SPEED_BOOST_DURATION,0x9b7ee172fae35099, CommandSetObjectSpeedBoostDuration );
|
|
|
|
// temporary
|
|
SCR_REGISTER_SECURE(CONVERT_OLD_PICKUP_TYPE_TO_NEW,0x9b788b7cb1c92c62, ConvertOldPickupTypeToHash);
|
|
|
|
SCR_REGISTER_SECURE(SET_FORCE_OBJECT_THIS_FRAME,0x8e21c2b8d76bd2c7, CommandSetForceObjectThisFrame);
|
|
|
|
SCR_REGISTER_SECURE(ONLY_CLEAN_UP_OBJECT_WHEN_OUT_OF_RANGE,0x13a78fce42e3b132, CommandOnlyCleanUpObjectWhenOutOfRange);
|
|
|
|
SCR_REGISTER_UNUSED(DOES_OBJECT_EXIST_WITH_DECORATOR,0xc637d97e669fafac, CommandDoesObjectExistWithDecorator);
|
|
|
|
SCR_REGISTER_SECURE(SET_DISABLE_COLLISIONS_BETWEEN_CARS_AND_CAR_PARACHUTE,0xe4998dcce92adeb9, CommandSetDisableCarCollisionsWithCarParachutes);
|
|
|
|
SCR_REGISTER_SECURE(SET_PROJECTILES_SHOULD_EXPLODE_ON_CONTACT,0x73c56b3110244a3b, CommandSetProjectilesShouldExplodeWhenHitting);
|
|
|
|
SCR_REGISTER_SECURE( SET_DRIVE_ARTICULATED_JOINT,0xfe483aa70caa8182, CommandSetDriveArticulatedJoint );
|
|
SCR_REGISTER_SECURE( SET_DRIVE_ARTICULATED_JOINT_WITH_INFLICTOR,0xcb795d4409baec14, CommandSetDriveArticulatedJointWithInflictor );
|
|
SCR_REGISTER_SECURE( SET_OBJECT_IS_A_PRESSURE_PLATE,0xe04446da0adbbeab, CommandSetObjectIsAPressurePlate );
|
|
SCR_REGISTER_UNUSED( GET_IS_PRESSURE_PLATE_PRESSED,0x5b2c00195589b9f9, CommandGetIsPressurePlatePressed );
|
|
SCR_REGISTER_SECURE( SET_WEAPON_IMPACTS_APPLY_GREATER_FORCE,0xd278f4541b205f55, CommandSetWeaponImpactsApplyGreaterForce );
|
|
SCR_REGISTER_SECURE( GET_IS_ARTICULATED_JOINT_AT_MIN_ANGLE,0xe90697e735a0e9fe, CommandGetIsArticulatedJointAtMinAngle );
|
|
SCR_REGISTER_SECURE(GET_IS_ARTICULATED_JOINT_AT_MAX_ANGLE,0xec2ec59776098a83, CommandGetIsArticulatedJointAtMaxAngle);
|
|
SCR_REGISTER_SECURE( SET_IS_OBJECT_ARTICULATED,0x447fadeab88b0db1, CommandSetObjectIsArticulated );
|
|
SCR_REGISTER_SECURE( SET_IS_OBJECT_BALL,0x70c27579df64816f, CommandSetObjectIsBall );
|
|
SCR_REGISTER_UNUSED( SET_OBJECT_POPS_TYRES,0x46ed143d558e9590, CommandSetObjectPopsTyres );
|
|
|
|
SCR_REGISTER_UNUSED( SET_OBJECT_ALBEDO_FLAG,0x0d7c43a3a5850b32, CommandSetObjectAlbedoFlag);
|
|
SCR_REGISTER_UNUSED( GET_OBJECT_ALBEDO_FLAG,0xcfc676c358a840ff, CommandGetObjectAlbedoFlag);
|
|
SCR_REGISTER_UNUSED( ENABLE_GLOBAL_ALBEDO_OBJECTS_SUPPORT,0xe8c6a8e6a6e0bd3b, CommandEnableGlobalAlbedoObjectsSupport);
|
|
|
|
}
|
|
} // end of namespace object_commands
|