Files
GTASource/game/pickups/PickupPlacement.h
expvintl 419f2e4752 init
2025-02-23 17:40:52 +08:00

291 lines
16 KiB
C++

#ifndef PICKUP_PLACEMENT_H
#define PICKUP_PLACEMENT_H
// Game headers
#include "network/Objects/Entities/NetObjPickupPlacement.h"
#include "pickups/Data/PickupIds.h"
#include "script/Handlers/GameScriptEntity.h"
#include "script/handlers/GameScriptHandler.h"
#include "script/handlers/GameScriptIds.h"
// framework includes
#include "fwscript/scripthandler.h"
class CPickup;
class CNetObjPickup;
class CPickupData;
//////////////////////////////////////////////////////////////////////////
// CPickupPlacement - Placement data for a pickup location. Exists whether
// the actual pickup object is there or not. Spawns a
// pickup object when the player gets close enough.
//////////////////////////////////////////////////////////////////////////
typedef u32 PlacementFlags;
class CPickupPlacement : public netGameObjectBase, public CGameScriptHandlerObject
{
public:
// placement flags
enum
{
// global (broadcast over network):
PLACEMENT_CREATION_FLAG_MAP = (1<<0), // map placements are treated as a special case due to their large number. These are the placements scattered around the map in a deathmatch, etc.
PLACEMENT_CREATION_FLAG_FIXED = (1<<1), // if set the spawned pickup will not activate its physics
PLACEMENT_CREATION_FLAG_REGENERATES = (1<<2), // if set the placement will regenerate the pickup after it has been collected
PLACEMENT_CREATION_FLAG_SNAP_TO_GROUND = (1<<3), // if set the placement will snap to the ground (within a range of 2.0 meters up/down)
PLACEMENT_CREATION_FLAG_ORIENT_TO_GROUND = (1<<4), // if set the placement will orient to the ground normal (if ground is found)
PLACEMENT_CREATION_FLAG_LOCAL_ONLY = (1<<5), // if set the placement will not be cloned on other machines
PLACEMENT_CREATION_FLAG_BLIPPED_SIMPLE = (1<<6), // if set the placement has a simple blip
PLACEMENT_CREATION_FLAG_BLIPPED_COMPLEX = (1<<7), // if set the placement has a complex blip
PLACEMENT_CREATION_FLAG_UPRIGHT = (1<<8), // if set the spawned pickup upright
PLACEMENT_CREATION_FLAG_ROTATE = (1<<9), // if set the spawned pickup will rotate
PLACEMENT_CREATION_FLAG_FACEPLAYER = (1<<10), // if set the spawned pickup will always face the player
PLACEMENT_CREATION_FLAG_HIDE_IN_PHOTOS = (1<<11), // if set the spawned pickup will not be rendered when the player is using the phone camera
PLACEMENT_CREATION_FLAG_PLAYER_GIFT = (1<<12), // if set the pickup is being dropped as a gift to another player
PLACEMENT_CREATION_FLAG_ON_OBJECT = (1<<13), // if set the pickup may be lying on an object - if so include objects in the probes when placing on ground
PLACEMENT_CREATION_FLAG_GLOW_IN_TEAM = (1<<14),
PLACEMENT_CREATION_FLAG_AUTO_EQUIP = (1<<15),
PLACEMENT_CREATION_FLAG_COLLECTABLE_IN_VEHICLE = (1<<16), // if set the pickup can be collected by a ped in a vehicle
PLACEMENT_CREATION_FLAG_DISABLE_WEAPON_HD_MODEL = (1<<17), // if set the weapon pickup will render SD model only (HD<->SD model switch will be disabled)
PLACEMENT_CREATION_FLAG_FORCE_DEFERRED_MODEL = (1<<18), // if set the pickup will render as deferred model (no transparency/alpha blending in this render mode)
#if __BANK
PLACEMENT_CREATION_FLAG_DEBUG_CREATED = (1<<19), // if set the spawned pickup was created by a rag widget
PLACEMENT_FLAG_NUM_CREATION_FLAGS = 20,
#else
PLACEMENT_FLAG_NUM_CREATION_FLAGS = 19,
#endif // __BANK
// If any more are added, you'll need to alter CPickupPlacementCreationDataNode::SIZEOF_PLACEMENT_FLAGS
// REMEMBER ADDTIONAL INTERNAL FLAGS BELOW!!
};
static const float DEFAULT_GLOW_OFFSET;
// a class holding custom script data that is only used for some pickups. The vast majority are map pickups, and we don't want to allocate this memory
// for them
class CPickupPlacementCustomScriptData
{
public:
CPickupPlacementCustomScriptData() :
m_customModelIndex(fwModelId::MI_INVALID),
m_pickupGlowOffset(DEFAULT_GLOW_OFFSET),
m_teamPermits(0),
m_radarBlip(INVALID_BLIP_ID)/*,
m_CloneToPlayersList(0)*/
{
}
FW_REGISTER_CLASS_POOL(CPickupPlacementCustomScriptData);
strLocalIndex m_customModelIndex; // a custom model the pickup can use instead of the one specified in the pickups meta data
s32 m_radarBlip; // the radar blip id (if this placement is blipped)
float m_pickupGlowOffset; // Offset applied to the glow, if any
TeamFlags m_teamPermits; // flags indicating which teams are allowed to collect this pickup
//PlayerFlags m_CloneToPlayersList; // used when we only want the pickup networked with a subset of players
};
protected:
// internal flags
enum
{
PLACEMENT_INTERNAL_FLAG_COLLECTED = (1<<PLACEMENT_FLAG_NUM_CREATION_FLAGS), // if set when the placement's pickup has been collected
PLACEMENT_INTERNAL_FLAG_DESTROYED = (1<<(PLACEMENT_FLAG_NUM_CREATION_FLAGS+1)), // if set the placement is being destroyed
PLACEMENT_INTERNAL_FLAG_PICKUP_DESTROYED = (1<<(PLACEMENT_FLAG_NUM_CREATION_FLAGS+2)), // if set the pickup was destroyed externally, via an explosion, etc
PLACEMENT_INTERNAL_FLAG_UNCOLLECTABLE = (1<<(PLACEMENT_FLAG_NUM_CREATION_FLAGS+3)), // if set the pickup will be locally uncollectable
PLACEMENT_INTERNAL_FLAG_FADE_WHEN_UNCOLLECTABLE = (1<<(PLACEMENT_FLAG_NUM_CREATION_FLAGS+4)), // if set the pickup will be faded out if it can't be collected (if blocked by script)
PLACEMENT_INTERNAL_FLAG_HIDE_WHEN_UNCOLLECTABLE = (1<<(PLACEMENT_FLAG_NUM_CREATION_FLAGS+5)), // if set the pickup object will not spawn if it can't be collected (if blocked by script)
PLACEMENT_FLAGS_LAST_FLAG = PLACEMENT_INTERNAL_FLAG_HIDE_WHEN_UNCOLLECTABLE
// If > 32, increase size of PlacementFlags
};
public:
FW_REGISTER_CLASS_POOL(CPickupPlacement);
CPickupPlacement(u32 pickupHash, Vector3& position, Vector3& orientation, PlacementFlags flags, u32 customModelIndex = fwModelId::MI_INVALID);
virtual ~CPickupPlacement();
u32 GetPickupHash() const;
const CPickupData* GetPickupData() const { return m_pPickupData; }
CPickup* GetPickup() const { return m_pPickup; }
void SetPickup(CPickup* pPickup);
Vector3& GetPickupPosition() { return m_pickupPosition; }
Vector3& GetPickupOrientation() { return m_pickupOrientation; }
float GetGenerationRange() const;
u32 GetRoomHash() const { return m_roomHashkey; }
void SetRoomHash(u32 hash) { m_roomHashkey = hash; }
u32 GetWeaponHash() const { return m_customWeaponHash; }
void SetWeaponHash(u32 hash) { m_customWeaponHash = hash; }
void SetAmount(u16 amount);
u32 GetAmount() const { return m_amount; }
u32 GetCustomModelHash() const;
s32 GetRadarBlip() const { return m_pCustomScriptData ? m_pCustomScriptData->m_radarBlip : INVALID_BLIP_ID; }
void SetRegenerationTime(u32 regenTime);
u32 GetRegenerationTime();
u32 GetCustomRegenerationTime() const { return m_customRegenTime; }
TeamFlags GetTeamPermits() const { return m_pCustomScriptData ? m_pCustomScriptData->m_teamPermits : 0; }
void SetTeamPermits(TeamFlags teams);
void AddTeamPermit(u8 team);
bool GeneratesNetworkedPickups() const;
void SetPickupGlowOffset(float f);
float GetPickupGlowOffset() const { return m_pCustomScriptData ? m_pCustomScriptData->m_pickupGlowOffset : DEFAULT_GLOW_OFFSET; }
void SetAmountCollected(u16 amount) { m_amountCollected = amount; }
u32 GetAmountCollected() const { return m_amountCollected; }
//void SetPlayersAvailability(PlayerFlags players);
//PlayerFlags GetPlayersAvailability() const { return m_pCustomScriptData ? m_pCustomScriptData->m_CloneToPlayersList : 0; }
// flags - TODO: replace all of these methods with IsFlagSet, etc! And use fwFlags
u32 GetFlags() const { return static_cast<u32>(m_flags); }
bool GetIsMapPlacement() const { return (m_flags & PLACEMENT_CREATION_FLAG_MAP) != 0; }
bool GetIsFixed() const { return (m_flags & PLACEMENT_CREATION_FLAG_FIXED) != 0; }
bool GetRegenerates() const { return (m_flags & PLACEMENT_CREATION_FLAG_REGENERATES) != 0; }
bool GetIsCollected() const { return (m_flags & PLACEMENT_INTERNAL_FLAG_COLLECTED) != 0; }
bool GetHasPickupBeenDestroyed() const { return (m_flags & PLACEMENT_INTERNAL_FLAG_PICKUP_DESTROYED) != 0; }
bool GetLocalOnly() const { return (m_flags & PLACEMENT_CREATION_FLAG_LOCAL_ONLY) != 0; }
void SetPickupHasBeenDestroyed(bool bLocallyDestroyed);
void SetHasSimpleBlip() { m_flags |= PLACEMENT_CREATION_FLAG_BLIPPED_SIMPLE; m_flags &= ~PLACEMENT_CREATION_FLAG_BLIPPED_COMPLEX; }
bool GetHasSimpleBlip() const { return (m_flags & PLACEMENT_CREATION_FLAG_BLIPPED_SIMPLE) != 0; }
void SetHasComplexBlip() { m_flags |= PLACEMENT_CREATION_FLAG_BLIPPED_COMPLEX; m_flags &= ~PLACEMENT_CREATION_FLAG_BLIPPED_SIMPLE; }
bool GetHasComplexBlip() const { return (m_flags & PLACEMENT_CREATION_FLAG_BLIPPED_COMPLEX) != 0; }
void SetIsBeingDestroyed() { m_flags |= PLACEMENT_INTERNAL_FLAG_DESTROYED; }
bool GetIsBeingDestroyed() const { return (m_flags & PLACEMENT_INTERNAL_FLAG_DESTROYED) != 0; }
void SetShouldSnapToGround() { m_flags |= PLACEMENT_CREATION_FLAG_SNAP_TO_GROUND; }
bool GetShouldSnapToGround() const { return (m_flags & PLACEMENT_CREATION_FLAG_SNAP_TO_GROUND) != 0; }
void SetShouldOrientToGround() { m_flags |= PLACEMENT_CREATION_FLAG_ORIENT_TO_GROUND; }
bool GetShouldOrientToGround() const { return (m_flags & PLACEMENT_CREATION_FLAG_ORIENT_TO_GROUND) != 0; }
void SetShouldBeUpright() { m_flags |= PLACEMENT_CREATION_FLAG_UPRIGHT; }
bool GetShouldBeUpright() const { return (m_flags & PLACEMENT_CREATION_FLAG_UPRIGHT) != 0; }
void SetShouldRotate() { m_flags |= PLACEMENT_CREATION_FLAG_ROTATE; }
bool GetShouldRotate() const { return (m_flags & PLACEMENT_CREATION_FLAG_ROTATE) != 0; }
void SetShouldFacePlayer() { m_flags |= PLACEMENT_CREATION_FLAG_FACEPLAYER; }
bool GetShouldFacePlayer() const { return (m_flags & PLACEMENT_CREATION_FLAG_FACEPLAYER) != 0; }
void SetGlowWhenInSameTeam() { m_flags |= PLACEMENT_CREATION_FLAG_GLOW_IN_TEAM; }
bool GetGlowWhenInSameTeam() const { return (m_flags & PLACEMENT_CREATION_FLAG_GLOW_IN_TEAM) != 0; }
void SetUncollectable(bool b);
bool GetUncollectable() const { return (m_flags & PLACEMENT_INTERNAL_FLAG_UNCOLLECTABLE) != 0; }
void SetTransparentWhenUncollectable(bool b);
bool GetTransparentWhenUncollectable() const { return (m_flags & PLACEMENT_INTERNAL_FLAG_FADE_WHEN_UNCOLLECTABLE) != 0; }
void SetHiddenWhenUncollectable(bool b);
bool GetHiddenWhenUncollectable() const { return (m_flags & PLACEMENT_INTERNAL_FLAG_HIDE_WHEN_UNCOLLECTABLE) != 0; }
bool GetIsHDWeaponModelDisabled() const { return (m_flags & PLACEMENT_CREATION_FLAG_DISABLE_WEAPON_HD_MODEL) != 0; }
bool GetForceDeferredModel() const { return (m_flags & PLACEMENT_CREATION_FLAG_FORCE_DEFERRED_MODEL) != 0; }
#if __BANK
void SetDebugCreated() { m_flags |= PLACEMENT_CREATION_FLAG_DEBUG_CREATED; }
bool GetDebugCreated() const { return (m_flags & PLACEMENT_CREATION_FLAG_DEBUG_CREATED) != 0; }
#else
void SetDebugCreated() { }
bool GetDebugCreated() const { return false; }
# endif // __BANK
void Update();
// returns true if in scope with any players or the given player. When in scope the placement spawns a pickup object.
bool GetInScope(CPed* pPlayerPed = NULL) const;
// creates the pickup object to represent this placement
CPickup* CreatePickup(CNetObjPickup* pNetObj = NULL);
// called when the pickup object representing this placement is collected
void Collect(CPed* pPedWhoGotIt);
// called when the pickup object representing this placement has to be regenerated
bool Regenerate();
// Destroys the pickup object representing this placement. Called when placement goes out of scope
void DestroyPickup();
// creates a blip for the placement if necessary (used by script commands)
s32 CreateBlip();
// removes any blip that exists for the placement (used by script commands)
void RemoveBlip();
// used by network code
bool IsScriptObject() const { return false; }
// called when the placement is registered with the network object manager as a network game starts
void OnNetworkRegistration() {}
// returns true if this placement can be collected (not blocked by script)
bool CanCollectScript() const;
// static functions
static bool GetInScope(const CPed& playerPed, const Vector3& placementPos, float range);
static void SetGenerationRangeMultiplier(float mult) { ms_generationRangeMultiplier = mult; }
static float GetGenerationRangeMultiplier() { return ms_generationRangeMultiplier; }
// scriptHandlerObject methods:
virtual unsigned GetType() const { return SCRIPT_HANDLER_OBJECT_TYPE_PICKUP; }
virtual void CreateScriptInfo(const scriptIdBase& scrId, const ScriptObjectId& objectId, const HostToken hostToken);
virtual void SetScriptInfo(const scriptObjInfoBase& info);
virtual scriptObjInfoBase* GetScriptInfo();
virtual const scriptObjInfoBase* GetScriptInfo() const;
virtual void SetScriptHandler(scriptHandler* handler);
virtual scriptHandler* GetScriptHandler() const { return m_pHandler; }
virtual void ClearScriptHandler() { m_pHandler = NULL; }
virtual void OnRegistration(bool newObject, bool hostObject);
virtual void OnUnregistration();
virtual bool IsCleanupRequired() const;
virtual void Cleanup();
virtual netObject* GetNetObject() const { return GetNetworkObject(); }
virtual fwEntity* GetEntity() const { return NULL; }
virtual bool HostObjectCanBeCreatedByClient() const { return GetIsMapPlacement(); }
#if __BANK
virtual void SpewDebugInfo(const char* scriptName) const;
#endif
virtual bool GetNoLongerNeeded() const { return false; }
virtual const char* GetLogName() const { return "PICKUP_PLACEMENT"; }
protected:
CPickupPlacementCustomScriptData* GetOrCreateCustomScriptData();
public:
// blip settings that can be altered by script commands
static float ms_customBlipScale;
static int ms_customBlipDisplay;
static int ms_customBlipPriority;
static int ms_customBlipSprite;
static int ms_customBlipColour;
static float ms_generationRangeMultiplier;
protected:
// Not allowed to copy construct or assign
CPickupPlacement(const CPickupPlacement &);
CPickupPlacement &operator=(const CPickupPlacement &);
CGameScriptObjInfo m_ScriptInfo; // the script that created this placement
u32 m_roomHashkey; // the key of the room this placement is in
u32 m_customWeaponHash; // weapon hash
Vector3 m_pickupPosition; // position of the pickup object when generated
Vector3 m_pickupOrientation; // euler angle orientation of the pickup object when generated
CPickup* m_pPickup; // ptr to the pickup object which this placement has generated
const CPickupData* m_pPickupData; // a pointer to the pickup data
scriptHandler* m_pHandler; // the script handler that this placement is registered with
CPickupPlacementCustomScriptData* m_pCustomScriptData; // some placements can set additional custom data
PlacementFlags m_flags; // placement flags
u16 m_customRegenTime; // a custom regeneration time in seconds, specific only to this placement. Overrides the value set in the pickup data.
u16 m_amount; // a variable amount used by some pickup types (eg money). This is used to get around the hard coded values specified in the Rave data.
u16 m_amountCollected; // the amount that is actually picked up when we consume this pickup placement.
public:
// declare as a network object
NETWORK_OBJECT_PTR_DECL_EX(CNetObjGame);
NETWORK_OBJECT_TYPE_DECL( CNetObjPickupPlacement, NET_OBJ_TYPE_PICKUP_PLACEMENT );
};
#endif // PICKUP_PLACEMENT_H