mirror of
https://gitlab.com/GaryOderNichts/re3-wiiu.git
synced 2024-12-25 09:11:50 +01:00
ped attractor: start
This commit is contained in:
parent
dc444b9ca0
commit
81ea6f0258
@ -956,7 +956,7 @@ CFileLoader::LoadCarPathNode(const char *line, int id, int node, bool waterPath)
|
|||||||
void
|
void
|
||||||
CFileLoader::Load2dEffect(const char *line)
|
CFileLoader::Load2dEffect(const char *line)
|
||||||
{
|
{
|
||||||
int id, r, g, b, a, type;
|
int id, r, g, b, a, type, ptype;
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
char corona[32], shadow[32];
|
char corona[32], shadow[32];
|
||||||
int shadowIntens, lightType, roadReflection, flare, flags, probability;
|
int shadowIntens, lightType, roadReflection, flare, flags, probability;
|
||||||
@ -1029,6 +1029,18 @@ CFileLoader::Load2dEffect(const char *line)
|
|||||||
effect->attractor.flags = flags;
|
effect->attractor.flags = flags;
|
||||||
effect->attractor.probability = probability;
|
effect->attractor.probability = probability;
|
||||||
break;
|
break;
|
||||||
|
case EFFECT_PED_ATTRACTOR:
|
||||||
|
sscanf(line, "%d %f %f %f %d %d %d %d %d %d %f %f %f %f %f %f",
|
||||||
|
&id, &x, &y, &z, &r, &g, &b, &a, &type,
|
||||||
|
&ptype,
|
||||||
|
&effect->pedattr.useDir.x,
|
||||||
|
&effect->pedattr.useDir.y,
|
||||||
|
&effect->pedattr.useDir.z,
|
||||||
|
&effect->pedattr.queueDir.x,
|
||||||
|
&effect->pedattr.queueDir.y,
|
||||||
|
&effect->pedattr.queueDir.z);
|
||||||
|
effect->pedattr.type = ptype;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTxdStore::PopCurrentTxd();
|
CTxdStore::PopCurrentTxd();
|
||||||
|
@ -78,7 +78,8 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVector &GetPosition(void){ return *(CVector*)&m_matrix.pos; }
|
const CVector &GetPosition(void) const { return *(CVector*)&m_matrix.pos; }
|
||||||
|
CVector& GetPosition(void) { return *(CVector*)&m_matrix.pos; }
|
||||||
CVector &GetRight(void) { return *(CVector*)&m_matrix.right; }
|
CVector &GetRight(void) { return *(CVector*)&m_matrix.right; }
|
||||||
CVector &GetForward(void) { return *(CVector*)&m_matrix.up; }
|
CVector &GetForward(void) { return *(CVector*)&m_matrix.up; }
|
||||||
CVector &GetUp(void) { return *(CVector*)&m_matrix.at; }
|
CVector &GetUp(void) { return *(CVector*)&m_matrix.at; }
|
||||||
|
@ -459,6 +459,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
|
|||||||
m_vecOffsetSeek.x = 0.0f;
|
m_vecOffsetSeek.x = 0.0f;
|
||||||
m_vecOffsetSeek.y = 0.0f;
|
m_vecOffsetSeek.y = 0.0f;
|
||||||
m_vecOffsetSeek.z = 0.0f;
|
m_vecOffsetSeek.z = 0.0f;
|
||||||
|
m_attractor = nil;
|
||||||
|
m_positionInQueue = -1;
|
||||||
m_pedFormation = FORMATION_UNDEFINED;
|
m_pedFormation = FORMATION_UNDEFINED;
|
||||||
m_collidingThingTimer = 0;
|
m_collidingThingTimer = 0;
|
||||||
m_nPedStateTimer = 0;
|
m_nPedStateTimer = 0;
|
||||||
@ -12658,8 +12660,8 @@ CPed::ProcessObjective(void)
|
|||||||
case OBJECTIVE_FOLLOW_CAR_IN_CAR:
|
case OBJECTIVE_FOLLOW_CAR_IN_CAR:
|
||||||
case OBJECTIVE_FIRE_AT_OBJ_FROM_VEHICLE:
|
case OBJECTIVE_FIRE_AT_OBJ_FROM_VEHICLE:
|
||||||
case OBJECTIVE_DESTROY_OBJ:
|
case OBJECTIVE_DESTROY_OBJ:
|
||||||
case OBJECTIVE_23:
|
case OBJECTIVE_26:
|
||||||
case OBJECTIVE_24:
|
case OBJECTIVE_27:
|
||||||
case OBJECTIVE_SET_LEADER:
|
case OBJECTIVE_SET_LEADER:
|
||||||
break;
|
break;
|
||||||
case OBJECTIVE_IDLE:
|
case OBJECTIVE_IDLE:
|
||||||
|
@ -19,6 +19,7 @@ class CObject;
|
|||||||
class CFire;
|
class CFire;
|
||||||
struct AnimBlendFrameData;
|
struct AnimBlendFrameData;
|
||||||
class CAnimBlendAssociation;
|
class CAnimBlendAssociation;
|
||||||
|
class CPedAttractor;
|
||||||
|
|
||||||
struct PedAudioData
|
struct PedAudioData
|
||||||
{
|
{
|
||||||
@ -154,6 +155,7 @@ enum eWaitState {
|
|||||||
enum eObjective : uint32 {
|
enum eObjective : uint32 {
|
||||||
OBJECTIVE_NONE,
|
OBJECTIVE_NONE,
|
||||||
OBJECTIVE_IDLE,
|
OBJECTIVE_IDLE,
|
||||||
|
OBJ_2,
|
||||||
OBJECTIVE_FLEE_TILL_SAFE,
|
OBJECTIVE_FLEE_TILL_SAFE,
|
||||||
OBJECTIVE_GUARD_SPOT,
|
OBJECTIVE_GUARD_SPOT,
|
||||||
OBJECTIVE_GUARD_AREA, // not implemented
|
OBJECTIVE_GUARD_AREA, // not implemented
|
||||||
@ -165,6 +167,8 @@ enum eObjective : uint32 {
|
|||||||
OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS,
|
OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS,
|
||||||
OBJECTIVE_GOTO_CHAR_ON_FOOT,
|
OBJECTIVE_GOTO_CHAR_ON_FOOT,
|
||||||
OBJECTIVE_FOLLOW_PED_IN_FORMATION,
|
OBJECTIVE_FOLLOW_PED_IN_FORMATION,
|
||||||
|
OBJ_14,
|
||||||
|
OBJ_15,
|
||||||
OBJECTIVE_LEAVE_VEHICLE,
|
OBJECTIVE_LEAVE_VEHICLE,
|
||||||
OBJECTIVE_ENTER_CAR_AS_PASSENGER,
|
OBJECTIVE_ENTER_CAR_AS_PASSENGER,
|
||||||
OBJECTIVE_ENTER_CAR_AS_DRIVER,
|
OBJECTIVE_ENTER_CAR_AS_DRIVER,
|
||||||
@ -175,8 +179,8 @@ enum eObjective : uint32 {
|
|||||||
OBJECTIVE_GOTO_AREA_ANY_MEANS,
|
OBJECTIVE_GOTO_AREA_ANY_MEANS,
|
||||||
OBJECTIVE_GOTO_AREA_ON_FOOT,
|
OBJECTIVE_GOTO_AREA_ON_FOOT,
|
||||||
OBJECTIVE_RUN_TO_AREA,
|
OBJECTIVE_RUN_TO_AREA,
|
||||||
OBJECTIVE_23, // not implemented
|
OBJECTIVE_26, // not implemented
|
||||||
OBJECTIVE_24, // not implemented
|
OBJECTIVE_27, // not implemented
|
||||||
OBJECTIVE_FIGHT_CHAR,
|
OBJECTIVE_FIGHT_CHAR,
|
||||||
OBJECTIVE_SET_LEADER,
|
OBJECTIVE_SET_LEADER,
|
||||||
OBJECTIVE_FOLLOW_ROUTE,
|
OBJECTIVE_FOLLOW_ROUTE,
|
||||||
@ -185,11 +189,32 @@ enum eObjective : uint32 {
|
|||||||
OBJECTIVE_CATCH_TRAIN,
|
OBJECTIVE_CATCH_TRAIN,
|
||||||
OBJECTIVE_BUY_ICE_CREAM,
|
OBJECTIVE_BUY_ICE_CREAM,
|
||||||
OBJECTIVE_STEAL_ANY_CAR,
|
OBJECTIVE_STEAL_ANY_CAR,
|
||||||
|
OBJ_36,
|
||||||
OBJECTIVE_MUG_CHAR,
|
OBJECTIVE_MUG_CHAR,
|
||||||
OBJECTIVE_FLEE_CAR,
|
OBJECTIVE_LEAVE_CAR_AND_DIE,
|
||||||
#ifdef VC_PED_PORTS
|
OBJECTIVE_USE_SEAT_ATTRACTOR,
|
||||||
OBJECTIVE_LEAVE_CAR_AND_DIE
|
OBJECTIVE_USE_ATM_ATTRACTOR,
|
||||||
#endif
|
OBJECTIVE_FLEE_CAR, // is it 41?
|
||||||
|
OBJ_42,
|
||||||
|
OBJECTIVE_USE_STOP_ATTRACTOR,
|
||||||
|
OBJECTIVE_USE_PIZZA_ATTRACTOR,
|
||||||
|
OBJECTIVE_USE_SHELTER_ATTRACTOR,
|
||||||
|
OBJ_46,
|
||||||
|
OBJ_47,
|
||||||
|
OBJ_48,
|
||||||
|
OBJ_49,
|
||||||
|
OBJ_50,
|
||||||
|
OBJ_51,
|
||||||
|
OBJ_52,
|
||||||
|
OBJECTIVE_USE_ICECREAM_ATTRACTOR,
|
||||||
|
OBJ_53,
|
||||||
|
OBJ_54,
|
||||||
|
OBJ_55,
|
||||||
|
OBJ_56,
|
||||||
|
OBJ_57,
|
||||||
|
OBJ_58,
|
||||||
|
OBJ_59
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -389,9 +414,10 @@ public:
|
|||||||
uint32 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
|
uint32 m_ped_flagI40 : 1; // bMakePedsRunToPhonesToReportCrimes makes use of this as runover by car indicator
|
||||||
uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
|
uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
|
||||||
|
|
||||||
uint32 bCarPassenger : 1;
|
uint32 bHasAlreadyUsedAttractor : 1; // 0x155 0x1
|
||||||
uint32 bMiamiViceCop : 1; //
|
uint32 bCarPassenger : 1; // 0x155 0x4
|
||||||
uint32 bDeadPedInFrontOfCar : 1;
|
uint32 bMiamiViceCop : 1; // 0x155 0x20
|
||||||
|
uint32 bDeadPedInFrontOfCar : 1; // 0x156 0x40
|
||||||
|
|
||||||
uint8 CharCreatedBy;
|
uint8 CharCreatedBy;
|
||||||
eObjective m_objective;
|
eObjective m_objective;
|
||||||
@ -457,6 +483,8 @@ public:
|
|||||||
bool bInVehicle;
|
bool bInVehicle;
|
||||||
float m_distanceToCountSeekDone;
|
float m_distanceToCountSeekDone;
|
||||||
|
|
||||||
|
CPedAttractor* m_attractor;
|
||||||
|
int32 m_positionInQueue;
|
||||||
CVehicle* m_vehicleInAccident;
|
CVehicle* m_vehicleInAccident;
|
||||||
|
|
||||||
bool bRunningToPhone;
|
bool bRunningToPhone;
|
||||||
@ -793,6 +821,8 @@ public:
|
|||||||
bool CanPedJumpThis(CEntity*);
|
bool CanPedJumpThis(CEntity*);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float, float, int);
|
||||||
|
|
||||||
bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
|
bool HasWeapon(uint8 weaponType) { return m_weapons[weaponType].m_eWeaponType == weaponType; }
|
||||||
CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
|
CWeapon &GetWeapon(uint8 weaponType) { return m_weapons[weaponType]; }
|
||||||
CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; }
|
CWeapon *GetWeapon(void) { return &m_weapons[m_currentWeapon]; }
|
||||||
|
559
src/peds/PedAttactor.cpp
Normal file
559
src/peds/PedAttactor.cpp
Normal file
@ -0,0 +1,559 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "PedAttractor.h"
|
||||||
|
|
||||||
|
#include "General.h"
|
||||||
|
#include "Vehicle.h"
|
||||||
|
|
||||||
|
const int gcMaxSizeOfAtmQueue = 1;
|
||||||
|
const int gcMaxSizeOfShelterQueue = 5;
|
||||||
|
|
||||||
|
CPedAttractorManager* GetPedAttractorManager()
|
||||||
|
{
|
||||||
|
static CPedAttractorManager manager;
|
||||||
|
return &manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVehicleToEffect::CVehicleToEffect(CVehicle* pVehicle) : m_pVehicle(pVehicle)
|
||||||
|
{
|
||||||
|
m_effects[1].col = CRGBA(0, 0, 0, 0);
|
||||||
|
m_effects[1].type = EFFECT_PED_ATTRACTOR;
|
||||||
|
m_effects[1].pos = CVector(2.0f, 1.0f, 0.0f);
|
||||||
|
m_effects[1].pedattr.useDir = CVector(-1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[1].pedattr.queueDir = CVector(-1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[1].pedattr.type = ATTRACTOR_ICECREAM;
|
||||||
|
|
||||||
|
m_effects[3].col = CRGBA(0, 0, 0, 0);
|
||||||
|
m_effects[3].type = EFFECT_PED_ATTRACTOR;
|
||||||
|
m_effects[3].pos = CVector(2.0f, -0.5f, 0.0f);
|
||||||
|
m_effects[3].pedattr.useDir = CVector(-1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[3].pedattr.queueDir = CVector(-1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[3].pedattr.type = ATTRACTOR_ICECREAM;
|
||||||
|
|
||||||
|
m_effects[0].col = CRGBA(0, 0, 0, 0);
|
||||||
|
m_effects[0].type = EFFECT_PED_ATTRACTOR;
|
||||||
|
m_effects[0].pos = CVector(-2.0f, 1.0f, 0.0f);
|
||||||
|
m_effects[0].pedattr.useDir = CVector(1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[0].pedattr.queueDir = CVector(1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[0].pedattr.type = ATTRACTOR_ICECREAM;
|
||||||
|
|
||||||
|
m_effects[2].col = CRGBA(0, 0, 0, 0);
|
||||||
|
m_effects[2].type = EFFECT_PED_ATTRACTOR;
|
||||||
|
m_effects[2].pos = CVector(-2.0f, -0.5f, 0.0f);
|
||||||
|
m_effects[2].pedattr.useDir = CVector(1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[2].pedattr.queueDir = CVector(1.0f, 0.0f, 0.0f);
|
||||||
|
m_effects[2].pedattr.type = ATTRACTOR_ICECREAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVehicleToEffect& CVehicleToEffect::From(const CVehicleToEffect& other)
|
||||||
|
{
|
||||||
|
m_pVehicle = other.m_pVehicle;
|
||||||
|
for (int i = 0; i < NUM_ATTRACTORS_FOR_ICECREAM_VAN; i++) {
|
||||||
|
m_effects[i].col = other.m_effects[i].col;
|
||||||
|
m_effects[i].type = other.m_effects[i].type;
|
||||||
|
m_effects[i].pos = other.m_effects[i].pos;
|
||||||
|
m_effects[i].pedattr = other.m_effects[i].pedattr;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const C2dEffect* CVehicleToEffect::ChooseEffect(const CVector& pos) const
|
||||||
|
{
|
||||||
|
if (!m_pVehicle)
|
||||||
|
return nil;
|
||||||
|
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetRight()) > 0.0f) {
|
||||||
|
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
|
||||||
|
return &m_effects[0];
|
||||||
|
else
|
||||||
|
return &m_effects[2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
|
||||||
|
return &m_effects[1];
|
||||||
|
else
|
||||||
|
return &m_effects[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CVehicleToEffect::HasThisEffect(C2dEffect* pEffect) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_ATTRACTORS_FOR_ICECREAM_VAN; i++) {
|
||||||
|
if (pEffect == &m_effects[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const C2dEffect* CPedAttractorManager::GetEffectForIceCreamVan(CVehicle* pVehicle, const CVector& pos)
|
||||||
|
{
|
||||||
|
if (!vVehicleToEffect.empty()) {
|
||||||
|
for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend(); ++assoc) {
|
||||||
|
if (assoc->GetVehicle() == pVehicle)
|
||||||
|
return assoc->ChooseEffect(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CVehicleToEffect effect(pVehicle);
|
||||||
|
vVehicleToEffect.push_back(effect);
|
||||||
|
return effect.ChooseEffect(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
CVehicle* CPedAttractorManager::GetIceCreamVanForEffect(C2dEffect* pEffect)
|
||||||
|
{
|
||||||
|
if (vVehicleToEffect.empty())
|
||||||
|
return false;
|
||||||
|
for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend(); ++assoc) {
|
||||||
|
if (assoc->HasThisEffect(pEffect))
|
||||||
|
return assoc->GetVehicle();
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CPedAttractor* CPedAttractorManager::FindAssociatedAttractor(const C2dEffect* pEffect, std::vector<CPedAttractor*> vecAttractors)
|
||||||
|
{
|
||||||
|
if (vecAttractors.empty())
|
||||||
|
return nil;
|
||||||
|
for (std::vector<CPedAttractor*>::const_iterator attractor = vecAttractors.cbegin(); attractor != vecAttractors.cend(); ++attractor) {
|
||||||
|
if ((*attractor)->GetEffect() == pEffect)
|
||||||
|
return *attractor;
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPedAttractorManager::RemoveIceCreamVanEffects(C2dEffect* pEffect)
|
||||||
|
{
|
||||||
|
CVehicle* pVehicle = GetIceCreamVanForEffect(pEffect);
|
||||||
|
if (!pVehicle)
|
||||||
|
return;
|
||||||
|
if (vVehicleToEffect.empty())
|
||||||
|
return;
|
||||||
|
for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend();) {
|
||||||
|
if (assoc->GetVehicle() != pVehicle)
|
||||||
|
return;
|
||||||
|
size_t total = 0;
|
||||||
|
for (size_t j = 0; j < NUM_ATTRACTORS_FOR_ICECREAM_VAN; j++) {
|
||||||
|
if (FindAssociatedAttractor(assoc->GetEffect(j), vIceCreamAttractors))
|
||||||
|
total++;
|
||||||
|
}
|
||||||
|
if (total > 0)
|
||||||
|
assoc++;
|
||||||
|
else
|
||||||
|
assoc = vVehicleToEffect.erase(assoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CPedAttractor::CPedAttractor(C2dEffect* pEffect, CMatrix const& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp) :
|
||||||
|
p2dEffect(p2dEffect),
|
||||||
|
m_nMaxPedsInAttractor(maxpeds),
|
||||||
|
m_fQueueDistance(qdist),
|
||||||
|
m_fTimeInWaitQueue(waitTime),
|
||||||
|
m_fTimeInApproachingQueue(approachTime),
|
||||||
|
field_30(unk8),
|
||||||
|
field_34(unk9),
|
||||||
|
m_fMaxPositionDisplacement(posdisp),
|
||||||
|
m_fMaxHeadingDisplacement(headdisp),
|
||||||
|
vecEffectPos(Multiply3x3(matrix, pEffect->pos)),
|
||||||
|
vecQueueDir(Multiply3x3(matrix, pEffect->pedattr.queueDir)),
|
||||||
|
vecUseDir(Multiply3x3(matrix, pEffect->pedattr.useDir))
|
||||||
|
{}
|
||||||
|
|
||||||
|
float CPedAttractor::ComputeDeltaHeading() const
|
||||||
|
{
|
||||||
|
return CGeneral::GetRandomNumberInRange(-m_fMaxHeadingDisplacement, m_fMaxHeadingDisplacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
float CPedAttractor::ComputeDeltaPos() const
|
||||||
|
{
|
||||||
|
return CGeneral::GetRandomNumberInRange(-m_fMaxPositionDisplacement, m_fMaxPositionDisplacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPedAttractor::ComputeAttractTime(int32 id, bool approacher, float& time) const
|
||||||
|
{
|
||||||
|
if (approacher)
|
||||||
|
time = m_fTimeInApproachingQueue;
|
||||||
|
else
|
||||||
|
time = m_fTimeInWaitQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPedAttractor::ComputeAttractPos(int32 qid, CVector& pos) const
|
||||||
|
{
|
||||||
|
if (!p2dEffect)
|
||||||
|
return;
|
||||||
|
pos = vecEffectPos - qid * vecQueueDir * m_fQueueDistance;
|
||||||
|
if (qid != 0) {
|
||||||
|
pos.x += ComputeDeltaPos();
|
||||||
|
pos.y += ComputeDeltaPos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CVector CPedShelterAttractor::GetDisplacement(int32 qid)
|
||||||
|
{
|
||||||
|
if (ms_displacements.empty()) {
|
||||||
|
int i = 0;
|
||||||
|
while (i < gcMaxSizeOfShelterQueue) {
|
||||||
|
float fRandomAngle = CGeneral::GetRandomNumberInRange(0.0f, TWOPI);
|
||||||
|
float fRandomOffset = CGeneral::GetRandomNumberInRange(0.0f, 2.0f);
|
||||||
|
CVector vecDisplacement(fRandomOffset * Sin(fRandomAngle), fRandomOffset * Cos(fRandomAngle), 0.0f);
|
||||||
|
bool close = false;
|
||||||
|
for (std::vector<CVector>::const_iterator v = ms_displacements.cbegin(); v != ms_displacements.cend(); ++v) {
|
||||||
|
if ((*v - vecDisplacement).Magnitude() < 1.0f) {
|
||||||
|
close = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!close) {
|
||||||
|
ms_displacements.push_back(vecDisplacement);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ms_displacements[qid];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPedAttractor::ComputeAttractHeading(int32 qid, float& heading) const
|
||||||
|
{
|
||||||
|
heading = CGeneral::GetRadianAngleBetweenPoints(qid != 0 ? vecQueueDir.x : vecUseDir.x, qid != 0 ? vecQueueDir.y : vecUseDir.y, 0.0f, 0.0f);
|
||||||
|
if (qid != 0)
|
||||||
|
heading += ComputeDeltaHeading();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPedShelterAttractor::ComputeAttractHeading(int32 qid, float& heading) const
|
||||||
|
{
|
||||||
|
heading = CGeneral::GetRandomNumberInRange(0.0f, TWOPI);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractor::RegisterPed(CPed* pPed)
|
||||||
|
{
|
||||||
|
for (std::vector<CPed*>::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) {
|
||||||
|
if (*pPedIt == pPed) {
|
||||||
|
vApproachingQueue.erase(pPedIt);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (GetNoOfRegisteredPeds() >= m_nMaxPedsInAttractor)
|
||||||
|
return 0;
|
||||||
|
vApproachingQueue.push_back(pPed);
|
||||||
|
CVector pos;
|
||||||
|
float heading;
|
||||||
|
float time;
|
||||||
|
int32 slot = ComputeFreeSlot();
|
||||||
|
ComputeAttractPos(slot, pos);
|
||||||
|
ComputeAttractHeading(slot, heading);
|
||||||
|
ComputeAttractTime(slot, false, time);
|
||||||
|
pPed->SetNewAttraction(this, pos, heading, time, slot);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsPedUsingAttractorOfThisType(int8 type, CPed* pPed)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case ATTRACTOR_ATM:
|
||||||
|
if (pPed->m_objective == OBJECTIVE_USE_ATM_ATTRACTOR)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case ATTRACTOR_SEAT:
|
||||||
|
if (pPed->m_objective == OBJECTIVE_USE_SEAT_ATTRACTOR)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case ATTRACTOR_STOP:
|
||||||
|
if (pPed->m_objective == OBJECTIVE_USE_STOP_ATTRACTOR || pPed->m_objective == OBJ_52 || pPed->m_objective == OBJECTIVE_IDLE)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case ATTRACTOR_PIZZA:
|
||||||
|
if (pPed->m_objective == OBJECTIVE_USE_PIZZA_ATTRACTOR || pPed->m_objective == OBJECTIVE_IDLE)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case ATTRACTOR_SHELTER:
|
||||||
|
if (pPed->m_objective == OBJECTIVE_USE_SHELTER_ATTRACTOR || pPed->m_objective == OBJ_48)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
case ATTRACTOR_ICECREAM:
|
||||||
|
if (pPed->m_objective == OBJECTIVE_USE_ICECREAM_ATTRACTOR || pPed->m_objective == OBJ_54)
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractor::DeRegisterPed(CPed* pPed)
|
||||||
|
{
|
||||||
|
for (std::vector<CPed*>::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) {
|
||||||
|
if (*pPedIt != pPed)
|
||||||
|
continue;
|
||||||
|
pPed->m_attractor = nil;
|
||||||
|
pPed->m_positionInQueue = -1;
|
||||||
|
pPed->bHasAlreadyUsedAttractor = true;
|
||||||
|
|
||||||
|
if (IsPedUsingAttractorOfThisType(p2dEffect->pedattr.type, pPed))
|
||||||
|
pPed->SetObjective(OBJECTIVE_NONE);
|
||||||
|
else if (pPed->GetPedState() != PED_IDLE && pPed->GetPedState() != PED_NONE) {
|
||||||
|
vApproachingQueue.erase(pPedIt);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return BroadcastDeparture(pPed);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractor::BroadcastArrival(CPed* pPed)
|
||||||
|
{
|
||||||
|
for (std::vector<CPed*>::const_iterator pPedIt = vWaitingQueue.cbegin(); pPedIt != vWaitingQueue.cend(); ++pPedIt) {
|
||||||
|
if (*pPedIt == pPed)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vWaitingQueue.push_back(pPed);
|
||||||
|
for (std::vector<CPed*>::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) {
|
||||||
|
if (*pPedIt == pPed) {
|
||||||
|
vApproachingQueue.erase(pPedIt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (std::vector<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) {
|
||||||
|
CPed* pPed = *pPedIt;
|
||||||
|
CVector pos;
|
||||||
|
float heading;
|
||||||
|
float time;
|
||||||
|
int32 slot = ComputeFreeSlot();
|
||||||
|
ComputeAttractPos(slot, pos);
|
||||||
|
ComputeAttractHeading(slot, heading);
|
||||||
|
ComputeAttractTime(slot, false, time);
|
||||||
|
pPed->SetNewAttraction(this, pos, heading, time, slot);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractor::BroadcastDeparture(CPed* pPed)
|
||||||
|
{
|
||||||
|
int qid = -1;
|
||||||
|
for (size_t i = 0; i < vWaitingQueue.size(); i++){
|
||||||
|
if (vWaitingQueue[i] == pPed)
|
||||||
|
qid = i;
|
||||||
|
}
|
||||||
|
if (qid < 0)
|
||||||
|
return false;
|
||||||
|
for (size_t i = qid + 1; i < vWaitingQueue.size(); i++) {
|
||||||
|
CVector pos;
|
||||||
|
float heading;
|
||||||
|
float time;
|
||||||
|
ComputeAttractPos(i - 1, pos);
|
||||||
|
ComputeAttractHeading(i - 1, heading);
|
||||||
|
ComputeAttractTime(i - 1, true, time);
|
||||||
|
pPed->SetNewAttraction(this, pos, heading, time, i - 1);
|
||||||
|
}
|
||||||
|
pPed->m_attractor = nil;
|
||||||
|
pPed->m_positionInQueue = -1;
|
||||||
|
pPed->bHasAlreadyUsedAttractor = true;
|
||||||
|
if (!IsPedUsingAttractorOfThisType(p2dEffect->pedattr.type, pPed)) {
|
||||||
|
if (pPed->GetPedState() == PED_IDLE || pPed->GetPedState() == PED_NONE)
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y));
|
||||||
|
}
|
||||||
|
else if (qid == 0)
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y));
|
||||||
|
else if (qid == vWaitingQueue.size() - 1)
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y));
|
||||||
|
else
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.z));
|
||||||
|
vWaitingQueue.erase(vWaitingQueue.cbegin() + qid);
|
||||||
|
for (std::vector<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) {
|
||||||
|
CPed* pPed = *pPedIt;
|
||||||
|
CVector pos;
|
||||||
|
float heading;
|
||||||
|
float time;
|
||||||
|
int32 slot = ComputeFreeSlot();
|
||||||
|
ComputeAttractPos(slot, pos);
|
||||||
|
ComputeAttractHeading(slot, heading);
|
||||||
|
ComputeAttractTime(slot, false, time);
|
||||||
|
pPed->SetNewAttraction(this, pos, heading, time, slot);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedShelterAttractor::BroadcastDeparture(CPed* pPed)
|
||||||
|
{
|
||||||
|
int qid = -1;
|
||||||
|
for (size_t i = 0; i < vWaitingQueue.size(); i++) {
|
||||||
|
if (vWaitingQueue[i] == pPed)
|
||||||
|
qid = i;
|
||||||
|
}
|
||||||
|
if (qid < 0)
|
||||||
|
return false;
|
||||||
|
pPed->m_attractor = nil;
|
||||||
|
pPed->m_positionInQueue = -1;
|
||||||
|
pPed->bHasAlreadyUsedAttractor = true;
|
||||||
|
if (!IsPedUsingAttractorOfThisType(p2dEffect->pedattr.type, pPed)) {
|
||||||
|
if (pPed->GetPedState() == PED_IDLE || pPed->GetPedState() == PED_NONE)
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y));
|
||||||
|
}
|
||||||
|
else if (qid == 0)
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(vecQueueDir.x, vecQueueDir.y));
|
||||||
|
else if (qid == vWaitingQueue.size() - 1)
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y));
|
||||||
|
else
|
||||||
|
pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.y, -vecQueueDir.z));
|
||||||
|
vWaitingQueue.erase(vWaitingQueue.cbegin() + qid);
|
||||||
|
for (std::vector<CPed*>::iterator pPedIt = vApproachingQueue.begin(); pPedIt != vApproachingQueue.end(); ++pPedIt) {
|
||||||
|
CPed* pPed = *pPedIt;
|
||||||
|
CVector pos;
|
||||||
|
float heading;
|
||||||
|
float time;
|
||||||
|
int32 slot = ComputeFreeSlot();
|
||||||
|
ComputeAttractPos(slot, pos);
|
||||||
|
ComputeAttractHeading(slot, heading);
|
||||||
|
ComputeAttractTime(slot, false, time);
|
||||||
|
pPed->SetNewAttraction(this, pos, heading, time, slot);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
CPedAttractor* CPedAttractorManager::RegisterPedWithAttractor(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix)
|
||||||
|
{
|
||||||
|
if (pEffect->type != EFFECT_PED_ATTRACTOR)
|
||||||
|
return nil;
|
||||||
|
if (IsPedRegisteredWithEffect(pPed))
|
||||||
|
return nil;
|
||||||
|
switch (pEffect->pedattr.type) {
|
||||||
|
case ATTRACTOR_ATM: return RegisterPed(pPed, pEffect, matrix, vAtmAttractors);
|
||||||
|
case ATTRACTOR_SEAT: return RegisterPed(pPed, pEffect, matrix, vSeatAttractors);
|
||||||
|
case ATTRACTOR_STOP: return RegisterPed(pPed, pEffect, matrix, vStopAttractors);
|
||||||
|
case ATTRACTOR_PIZZA: return RegisterPed(pPed, pEffect, matrix, vPizzaAttractors);
|
||||||
|
case ATTRACTOR_SHELTER: return RegisterPed(pPed, pEffect, matrix, vShelterAttractors);
|
||||||
|
case ATTRACTOR_ICECREAM: return RegisterPed(pPed, pEffect, matrix, vIceCreamAttractors);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractorManager::DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor)
|
||||||
|
{
|
||||||
|
if (!pAttractor)
|
||||||
|
return false;
|
||||||
|
if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
|
||||||
|
return nil;
|
||||||
|
if (IsPedRegisteredWithEffect(pPed))
|
||||||
|
return nil;
|
||||||
|
switch (pAttractor->GetEffect()->pedattr.type) {
|
||||||
|
case ATTRACTOR_ATM: return DeRegisterPed(pPed, pAttractor, vAtmAttractors);
|
||||||
|
case ATTRACTOR_SEAT: return DeRegisterPed(pPed, pAttractor, vSeatAttractors);
|
||||||
|
case ATTRACTOR_STOP: return DeRegisterPed(pPed, pAttractor, vStopAttractors);
|
||||||
|
case ATTRACTOR_PIZZA: return DeRegisterPed(pPed, pAttractor, vPizzaAttractors);
|
||||||
|
case ATTRACTOR_SHELTER: return DeRegisterPed(pPed, pAttractor, vShelterAttractors);
|
||||||
|
case ATTRACTOR_ICECREAM: return DeRegisterPed(pPed, pAttractor, vIceCreamAttractors);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractorManager::BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor)
|
||||||
|
{
|
||||||
|
if (!pAttractor)
|
||||||
|
return false;
|
||||||
|
if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
|
||||||
|
return nil;
|
||||||
|
if (IsPedRegisteredWithEffect(pPed))
|
||||||
|
return nil;
|
||||||
|
switch (pAttractor->GetEffect()->pedattr.type) {
|
||||||
|
case ATTRACTOR_ATM: return BroadcastArrival(pPed, pAttractor, vAtmAttractors);
|
||||||
|
case ATTRACTOR_SEAT: return BroadcastArrival(pPed, pAttractor, vSeatAttractors);
|
||||||
|
case ATTRACTOR_STOP: return BroadcastArrival(pPed, pAttractor, vStopAttractors);
|
||||||
|
case ATTRACTOR_PIZZA: return BroadcastArrival(pPed, pAttractor, vPizzaAttractors);
|
||||||
|
case ATTRACTOR_SHELTER: return BroadcastArrival(pPed, pAttractor, vShelterAttractors);
|
||||||
|
case ATTRACTOR_ICECREAM: return BroadcastArrival(pPed, pAttractor, vIceCreamAttractors);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractorManager::BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor)
|
||||||
|
{
|
||||||
|
if (!pAttractor)
|
||||||
|
return false;
|
||||||
|
if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
|
||||||
|
return nil;
|
||||||
|
if (IsPedRegisteredWithEffect(pPed))
|
||||||
|
return nil;
|
||||||
|
switch (pAttractor->GetEffect()->pedattr.type) {
|
||||||
|
case ATTRACTOR_ATM: return BroadcastDeparture(pPed, pAttractor, vAtmAttractors);
|
||||||
|
case ATTRACTOR_SEAT: return BroadcastDeparture(pPed, pAttractor, vSeatAttractors);
|
||||||
|
case ATTRACTOR_STOP: return BroadcastDeparture(pPed, pAttractor, vStopAttractors);
|
||||||
|
case ATTRACTOR_PIZZA: return BroadcastDeparture(pPed, pAttractor, vPizzaAttractors);
|
||||||
|
case ATTRACTOR_SHELTER: return BroadcastDeparture(pPed, pAttractor, vShelterAttractors);
|
||||||
|
case ATTRACTOR_ICECREAM: return BroadcastDeparture(pPed, pAttractor, vIceCreamAttractors);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractorManager::IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor)
|
||||||
|
{
|
||||||
|
if (!pAttractor)
|
||||||
|
return false;
|
||||||
|
if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
|
||||||
|
return nil;
|
||||||
|
if (IsPedRegisteredWithEffect(pPed))
|
||||||
|
return nil;
|
||||||
|
switch (pAttractor->GetEffect()->pedattr.type) {
|
||||||
|
case ATTRACTOR_ATM: return IsAtHeadOfQueue(pPed, pAttractor, vAtmAttractors);
|
||||||
|
case ATTRACTOR_SEAT: return IsAtHeadOfQueue(pPed, pAttractor, vSeatAttractors);
|
||||||
|
case ATTRACTOR_STOP: return IsAtHeadOfQueue(pPed, pAttractor, vStopAttractors);
|
||||||
|
case ATTRACTOR_PIZZA: return IsAtHeadOfQueue(pPed, pAttractor, vPizzaAttractors);
|
||||||
|
case ATTRACTOR_SHELTER: return IsAtHeadOfQueue(pPed, pAttractor, vShelterAttractors);
|
||||||
|
case ATTRACTOR_ICECREAM: return IsAtHeadOfQueue(pPed, pAttractor, vIceCreamAttractors);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractorManager::IsInQueue(CPed* pPed, CPedAttractor* pAttractor)
|
||||||
|
{
|
||||||
|
if (!pAttractor)
|
||||||
|
return false;
|
||||||
|
if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
|
||||||
|
return nil;
|
||||||
|
if (IsPedRegisteredWithEffect(pPed))
|
||||||
|
return nil;
|
||||||
|
switch (pAttractor->GetEffect()->pedattr.type) {
|
||||||
|
case ATTRACTOR_ATM: return IsInQueue(pPed, pAttractor, vAtmAttractors);
|
||||||
|
case ATTRACTOR_SEAT: return IsInQueue(pPed, pAttractor, vSeatAttractors);
|
||||||
|
case ATTRACTOR_STOP: return IsInQueue(pPed, pAttractor, vStopAttractors);
|
||||||
|
case ATTRACTOR_PIZZA: return IsInQueue(pPed, pAttractor, vPizzaAttractors);
|
||||||
|
case ATTRACTOR_SHELTER: return IsInQueue(pPed, pAttractor, vShelterAttractors);
|
||||||
|
case ATTRACTOR_ICECREAM: return IsInQueue(pPed, pAttractor, vIceCreamAttractors);
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPedAttractorManager::IsPedRegisteredWithEffect(CPed* pPed)
|
||||||
|
{
|
||||||
|
return IsPedRegistered(pPed, vAtmAttractors) ||
|
||||||
|
IsPedRegistered(pPed, vSeatAttractors) ||
|
||||||
|
IsPedRegistered(pPed, vStopAttractors) ||
|
||||||
|
IsPedRegistered(pPed, vPizzaAttractors) ||
|
||||||
|
IsPedRegistered(pPed, vShelterAttractors) ||
|
||||||
|
IsPedRegistered(pPed, vIceCreamAttractors);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ComputeEffectPos(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos)
|
||||||
|
{
|
||||||
|
pos = matrix.GetPosition() + Multiply3x3(matrix, pEffect->pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPedAttractor* CPedAttractorManager::RegisterPed(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix, std::vector<CPedAttractor*>& vecAttractors)
|
||||||
|
{
|
||||||
|
CPedAttractor* pRegisteredAttractor = nil;
|
||||||
|
for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
|
||||||
|
CPedAttractor* pAttractor = *pAttractorIt;
|
||||||
|
CVector vEffectPos;
|
||||||
|
ComputeEffectPos(pAttractor->GetEffect(), matrix, vEffectPos);
|
||||||
|
if (pAttractor->GetEffect() == pEffect && vEffectPos == pAttractor->GetEffectPos()) {
|
||||||
|
if (!IsApproachable(pEffect, matrix, pAttractor->ComputeFreeSlot(), pPed))
|
||||||
|
return false;
|
||||||
|
pRegisteredAttractor = pAttractor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pRegisteredAttractor || !IsApproachable(pEffect, matrix, 0, pPed)) {
|
||||||
|
if (pRegisteredAttractor)
|
||||||
|
pRegisteredAttractor->RegisterPed(pPed);
|
||||||
|
return pRegisteredAttractor;
|
||||||
|
}
|
||||||
|
switch (pEffect->pedattr.type) {
|
||||||
|
case ATTRACTOR_ATM: vecAttractors.push_back(new CPedAtmAttractor(pEffect, matrix, gcMaxSizeOfAtmQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.15f, 0.1f, 0.1f)); break;
|
||||||
|
}
|
||||||
|
if (pRegisteredAttractor)
|
||||||
|
pRegisteredAttractor->RegisterPed(pPed);
|
||||||
|
return pRegisteredAttractor;
|
||||||
|
}
|
188
src/peds/PedAttractor.h
Normal file
188
src/peds/PedAttractor.h
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "common.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "2dEffect.h"
|
||||||
|
#include "Ped.h"
|
||||||
|
|
||||||
|
#define NUM_ATTRACTORS_FOR_ICECREAM_VAN 4
|
||||||
|
|
||||||
|
enum ePedAttractorType
|
||||||
|
{
|
||||||
|
ATTRACTOR_ATM = 0,
|
||||||
|
ATTRACTOR_SEAT,
|
||||||
|
ATTRACTOR_STOP,
|
||||||
|
ATTRACTOR_PIZZA,
|
||||||
|
ATTRACTOR_SHELTER,
|
||||||
|
ATTRACTOR_ICECREAM
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedAttractor
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
C2dEffect* p2dEffect;
|
||||||
|
std::vector<CPed*> vApproachingQueue;
|
||||||
|
std::vector<CPed*> vWaitingQueue;
|
||||||
|
int32 m_nMaxPedsInAttractor;
|
||||||
|
float m_fQueueDistance;
|
||||||
|
float m_fTimeInWaitQueue;
|
||||||
|
float m_fTimeInApproachingQueue;
|
||||||
|
float field_30;
|
||||||
|
float field_34;
|
||||||
|
float m_fMaxPositionDisplacement;
|
||||||
|
float m_fMaxHeadingDisplacement;
|
||||||
|
CVector vecEffectPos;
|
||||||
|
CVector vecQueueDir;
|
||||||
|
CVector vecUseDir;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual float GetHeadOfQueueWaitTime() { return 0.0f; }
|
||||||
|
virtual ~CPedAttractor() {};
|
||||||
|
virtual ePedAttractorType GetType() const = 0;
|
||||||
|
virtual void UpdatePedStateOnDeparture() const = 0;
|
||||||
|
virtual bool IsAtHeadOfQueue(CPed* pPed) const { return vWaitingQueue.front() == pPed; }
|
||||||
|
virtual void ComputeAttractPos(int32 id, CVector& pos) const;
|
||||||
|
virtual void ComputeAttractHeading(int32 id, float& pHeading) const;
|
||||||
|
virtual bool BroadcastDeparture(CPed* pPed);
|
||||||
|
|
||||||
|
bool IsRegisteredWithPed(CPed* pPed) const;
|
||||||
|
bool DeRegisterPed(CPed* pPed);
|
||||||
|
float ComputeDeltaHeading() const;
|
||||||
|
float ComputeDeltaPos() const;
|
||||||
|
void ComputeAttractTime(int32 id, bool, float& time) const;
|
||||||
|
int32 GetNoOfRegisteredPeds() const { return vWaitingQueue.size() + vApproachingQueue.size(); }
|
||||||
|
int32 ComputeFreeSlot() const { return vWaitingQueue.size(); }
|
||||||
|
bool IsInQueue(CPed*) const;
|
||||||
|
bool RegisterPed(CPed*);
|
||||||
|
bool BroadcastArrival(CPed*);
|
||||||
|
|
||||||
|
CPedAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp);
|
||||||
|
|
||||||
|
C2dEffect* GetEffect() const { return p2dEffect; }
|
||||||
|
const CVector& GetEffectPos() const { return vecEffectPos; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedAtmAttractor : public CPedAttractor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ePedAttractorType GetType() const override { return ATTRACTOR_ATM; };
|
||||||
|
virtual void UpdatePedStateOnDeparture() const override;
|
||||||
|
CPedAtmAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp) :
|
||||||
|
CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, unk8, unk9, posdisp, headdisp)
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedIceCreamAttractor : public CPedAttractor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ePedAttractorType GetType() const override { return ATTRACTOR_ICECREAM; }
|
||||||
|
virtual void UpdatePedStateOnDeparture() const override;
|
||||||
|
CPedIceCreamAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp) :
|
||||||
|
CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, unk8, unk9, posdisp, headdisp)
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedPizzaAttractor : public CPedAttractor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual float GetHeadOfQueueWaitTime() override { return 2000.0f; }
|
||||||
|
virtual ePedAttractorType GetType() const override { return ATTRACTOR_PIZZA; }
|
||||||
|
virtual void UpdatePedStateOnDeparture() const override;
|
||||||
|
CPedPizzaAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp) :
|
||||||
|
CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, unk8, unk9, posdisp, headdisp)
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedSeatAttractor : public CPedAttractor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ePedAttractorType GetType() const override { return ATTRACTOR_SEAT; }
|
||||||
|
virtual void UpdatePedStateOnDeparture() const override;
|
||||||
|
CPedSeatAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp) :
|
||||||
|
CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, unk8, unk9, posdisp, headdisp)
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedShelterAttractor : public CPedAttractor
|
||||||
|
{
|
||||||
|
static std::vector<CVector> ms_displacements;
|
||||||
|
public:
|
||||||
|
virtual ePedAttractorType GetType() const override { return ATTRACTOR_SHELTER; }
|
||||||
|
virtual bool BroadcastDeparture(CPed*) override;
|
||||||
|
virtual void UpdatePedStateOnDeparture() const override;
|
||||||
|
virtual bool IsAtHeadOfQueue(CPed* pPed) const override { return true; }
|
||||||
|
virtual void ComputeAttractPos(int qid, CVector& pos) const override;
|
||||||
|
virtual void ComputeAttractHeading(int qid, float& heading) const override;
|
||||||
|
|
||||||
|
CPedShelterAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp) :
|
||||||
|
CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, unk8, unk9, posdisp, headdisp)
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
CVector GetDisplacement(int32 qid);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedStopAttractor : public CPedAttractor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ePedAttractorType GetType() const override { return ATTRACTOR_STOP; }
|
||||||
|
virtual void UpdatePedStateOnDeparture() const override;
|
||||||
|
|
||||||
|
CPedStopAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float unk8, float unk9, float posdisp, float headdisp) :
|
||||||
|
CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, unk8, unk9, posdisp, headdisp)
|
||||||
|
{};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CVehicleToEffect
|
||||||
|
{
|
||||||
|
CVehicle* m_pVehicle;
|
||||||
|
C2dEffect m_effects[NUM_ATTRACTORS_FOR_ICECREAM_VAN];
|
||||||
|
|
||||||
|
public:
|
||||||
|
CVehicleToEffect(CVehicle* pVehicle);
|
||||||
|
const C2dEffect* ChooseEffect(const CVector& pos) const;
|
||||||
|
CVehicleToEffect& From(const CVehicleToEffect& other);
|
||||||
|
CVehicleToEffect& operator=(const CVehicleToEffect& other) { return From(other); }
|
||||||
|
~CVehicleToEffect() { m_pVehicle = nil; }
|
||||||
|
CVehicle* GetVehicle() const { return m_pVehicle; }
|
||||||
|
bool HasThisEffect(C2dEffect* pEffect) const;
|
||||||
|
const C2dEffect* GetEffect(int32 i) const { return &m_effects[i]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPedAttractorManager
|
||||||
|
{
|
||||||
|
std::vector<CPedAttractor*> vAtmAttractors;
|
||||||
|
std::vector<CPedAttractor*> vSeatAttractors;
|
||||||
|
std::vector<CPedAttractor*> vStopAttractors;
|
||||||
|
std::vector<CPedAttractor*> vPizzaAttractors;
|
||||||
|
std::vector<CPedAttractor*> vShelterAttractors;
|
||||||
|
std::vector<CPedAttractor*> vIceCreamAttractors;
|
||||||
|
std::vector<CVehicleToEffect> vVehicleToEffect;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CPedAttractor* RegisterPedWithAttractor(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix);
|
||||||
|
CPedAttractor* RegisterPed(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix, std::vector<CPedAttractor*>& vecAttractors);
|
||||||
|
bool BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor);
|
||||||
|
bool BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors);
|
||||||
|
const C2dEffect* GetEffectForIceCreamVan(CVehicle* pVehicle, const CVector& pos);
|
||||||
|
void ComputeEffectQueueDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& dir);
|
||||||
|
bool IsApproachable(C2dEffect* pEffect, const CMatrix& matrix, int32, CPed* pPed);
|
||||||
|
void ComputeEffectUseDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& dir);
|
||||||
|
void ComputeEffectPos(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos);
|
||||||
|
void RemoveIceCreamVanEffects(C2dEffect* pEffect);
|
||||||
|
bool HasEmptySlot(const C2dEffect* pEffect);
|
||||||
|
const CPedAttractor* FindAssociatedAttractor(const C2dEffect* pEffect, std::vector<CPedAttractor*> vecAttractors);
|
||||||
|
bool IsInQueue(CPed* pPed, CPedAttractor* pAttractor);
|
||||||
|
bool IsInQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*> vecAttractors);
|
||||||
|
bool IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor);
|
||||||
|
bool IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*> vecAttractors);
|
||||||
|
bool BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor);
|
||||||
|
bool BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*> vecAttractors);
|
||||||
|
bool DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor);
|
||||||
|
bool DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*> vecAttractors);
|
||||||
|
bool IsPedRegisteredWithEffect(CPed* pPed);
|
||||||
|
bool IsPedRegistered(CPed* pPed, std::vector<CPedAttractor*> vecAttractors);
|
||||||
|
CVehicle* GetIceCreamVanForEffect(C2dEffect* pEffect);
|
||||||
|
};
|
||||||
|
|
||||||
|
CPedAttractorManager* GetPedAttractorManager();
|
@ -3,7 +3,8 @@
|
|||||||
enum {
|
enum {
|
||||||
EFFECT_LIGHT,
|
EFFECT_LIGHT,
|
||||||
EFFECT_PARTICLE,
|
EFFECT_PARTICLE,
|
||||||
EFFECT_ATTRACTOR
|
EFFECT_ATTRACTOR,
|
||||||
|
EFFECT_PED_ATTRACTOR
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -63,6 +64,11 @@ public:
|
|||||||
uint8 flags;
|
uint8 flags;
|
||||||
uint8 probability;
|
uint8 probability;
|
||||||
};
|
};
|
||||||
|
struct PedAttractor {
|
||||||
|
CVector useDir;
|
||||||
|
CVector queueDir;
|
||||||
|
int8 type;
|
||||||
|
};
|
||||||
|
|
||||||
CVector pos;
|
CVector pos;
|
||||||
CRGBA col;
|
CRGBA col;
|
||||||
@ -71,6 +77,7 @@ public:
|
|||||||
Light light;
|
Light light;
|
||||||
Particle particle;
|
Particle particle;
|
||||||
Attractor attractor;
|
Attractor attractor;
|
||||||
|
PedAttractor pedattr;
|
||||||
};
|
};
|
||||||
|
|
||||||
C2dEffect(void) {}
|
C2dEffect(void) {}
|
||||||
|
Loading…
Reference in New Issue
Block a user