mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-04 20:57:49 +00:00
fahhh
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/HumanoidState.h"
|
||||
|
||||
namespace RBX {
|
||||
namespace HUMAN {
|
||||
|
||||
|
||||
class Balancing : public HumanoidState
|
||||
{
|
||||
private:
|
||||
float kP; // units: 1/sec^2 torque = kP * momentOfInertia * rotation
|
||||
float kD; // units: 1/sec torque = kD * momentOfInertia * rotVelocity
|
||||
|
||||
Vector3 lastBalanceTorque;
|
||||
int tick;
|
||||
|
||||
static int balanceRate(double torqueMag);
|
||||
static int balanceRateForPGS();
|
||||
protected:
|
||||
static const float maxTorqueComponent() {return 4000.0f;} // units: 1/sec^2 torque <= maxTorqueComponent * momentOfInertia
|
||||
|
||||
void setBalanceP(float P) { kP = P; };
|
||||
void setBalanceD(float D) { kD = D; };
|
||||
|
||||
// Humanoid::State
|
||||
/*override*/ void onComputeForceImpl();
|
||||
|
||||
public:
|
||||
Balancing(Humanoid* humanoid, StateType priorState);
|
||||
Balancing(Humanoid* humanoid, StateType priorState, const float kP, const float kD);
|
||||
};
|
||||
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace RBX
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/HumanoidState.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
// pure simulation!
|
||||
|
||||
extern const char* const sDead;
|
||||
class Dead : public Named<HumanoidState, sDead>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return DEAD;}
|
||||
/*override*/ void onStepImpl();
|
||||
/*override*/ void onSimulatorStepImpl(float stepDt);
|
||||
/*override*/ void onComputeForceImpl() {}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
public:
|
||||
Dead(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
|
||||
extern const char* const sFallingDown;
|
||||
class FallingDown : public Named<HumanoidState, sFallingDown>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return FALLING_DWN;}
|
||||
/*override*/ void onComputeForceImpl() {}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
public:
|
||||
FallingDown(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
extern const char* const sPhysics;
|
||||
class Physics : public Named<HumanoidState, sPhysics>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return PHYSICS;}
|
||||
/*override*/ void onComputeForceImpl() {}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
public:
|
||||
Physics(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace RBX
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/Balancing.h"
|
||||
#include "Util/Name.h"
|
||||
|
||||
namespace RBX {
|
||||
namespace HUMAN {
|
||||
|
||||
// Flying occurs when there's no ground below you. You have the ability
|
||||
// to turn around the y-axis, but not much else.
|
||||
extern const char* const sFlying;
|
||||
|
||||
class Flying : public Named<Balancing, sFlying>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return FLYING;}
|
||||
|
||||
protected:
|
||||
// Humanoid::State
|
||||
/*override*/ void onSimulatorStepImpl(float stepDt);
|
||||
/*override*/ void onComputeForceImpl();
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
|
||||
public:
|
||||
Flying(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/Balancing.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sFreefall;
|
||||
|
||||
class Freefall : public Named<Balancing, sFreefall>
|
||||
{
|
||||
private:
|
||||
typedef Named<Balancing, sFreefall> Super;
|
||||
bool initialized; // hack- some data is bad in the constructor - do first time through;
|
||||
Vector3 initialLinearVelocity;
|
||||
Velocity desiredVelocity; // Y is world-up
|
||||
float torsoFriction; // I set both of these to zero!
|
||||
float headFriction;
|
||||
|
||||
/*override*/ StateType getStateType() const {return FREE_FALL;}
|
||||
|
||||
/*override*/ void onSimulatorStepImpl(float stepDt);
|
||||
|
||||
/*override*/ void onComputeForceImpl();
|
||||
|
||||
/*override*/ int ladderCheckRate() { return 0; }
|
||||
|
||||
/*override*/ bool armsShouldCollide() const {return false;}
|
||||
/*override*/ bool legsShouldCollide() const {return false;}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
|
||||
static float characterVelocityInfluence();
|
||||
static float floorVelocityInfluence();
|
||||
static float velocityDecay();
|
||||
|
||||
public:
|
||||
Freefall(Humanoid* humanoid, StateType priorState);
|
||||
|
||||
~Freefall();
|
||||
|
||||
static float kTurnSpeed();
|
||||
static float kTurnSpeedForPGS();
|
||||
static const float kTurnAccelMax() {return 20000.0f * kTurnSpeed();} // units: 1/sec^2
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/Humanoid.h"
|
||||
#include "Humanoid/Balancing.h"
|
||||
#include "Util/Name.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sGettingUp;
|
||||
|
||||
class GettingUp : public Named<Balancing, sGettingUp>
|
||||
{
|
||||
protected:
|
||||
/*override*/ StateType getStateType() const {return GETTING_UP;}
|
||||
|
||||
/*override*/ bool armsShouldCollide() const {return false;}
|
||||
/*override*/ bool legsShouldCollide() const {return false;}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
|
||||
public:
|
||||
GettingUp(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
} // HUMAN
|
||||
} // namespace
|
||||
|
||||
@@ -0,0 +1,621 @@
|
||||
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "V8DataModel/ICharacterSubject.h"
|
||||
#include "V8DataModel/IModelModifier.h"
|
||||
#include "V8DataModel/PartInstance.h"
|
||||
#include "V8DataModel/Tool.h"
|
||||
#include "V8World/KernelJoint.h"
|
||||
#include "V8World/Primitive.h"
|
||||
#include "Util/SteppedInstance.h"
|
||||
#include "GfxBase/IAdornable.h"
|
||||
#include "Util/RunStateOwner.h"
|
||||
#include "Util/ContentFilter.h"
|
||||
#include "Util/HeapValue.h"
|
||||
#include "Humanoid/StatusInstance.h"
|
||||
#include "Humanoid/HumanoidState.h"
|
||||
|
||||
namespace RBX {
|
||||
class World;
|
||||
class RunService;
|
||||
class Controller;
|
||||
class Primitive;
|
||||
class PartInstance;
|
||||
class ModelInstance;
|
||||
class JointInstance;
|
||||
class DataModelMesh;
|
||||
class Decal;
|
||||
class Weld;
|
||||
class Animator;
|
||||
|
||||
namespace HUMAN {
|
||||
class HumanoidState;
|
||||
}
|
||||
|
||||
namespace Soundscape {
|
||||
class SoundChannel;
|
||||
}
|
||||
|
||||
extern const char* const sHumanoid;
|
||||
class Humanoid
|
||||
: public DescribedCreatable<Humanoid, Instance, sHumanoid>
|
||||
, public KernelJoint // Implements "computeForce"
|
||||
, public IAdornable
|
||||
, public ICharacterSubject
|
||||
, public IModelModifier
|
||||
, public IStepped
|
||||
{
|
||||
public:
|
||||
enum NameOcclusion
|
||||
{
|
||||
NAME_OCCLUSION_NONE = 0,
|
||||
NAME_OCCLUSION_ENEMY = 1,
|
||||
NAME_OCCLUSION_ALL = 2,
|
||||
};
|
||||
|
||||
enum HumanoidDisplayDistanceType
|
||||
{
|
||||
HUMANOID_DISPLAY_DISTANCE_TYPE_VIEWER = 0,
|
||||
HUMANOID_DISPLAY_DISTANCE_TYPE_SUBJECT = 1,
|
||||
HUMANOID_DISPLAY_DISTANCE_TYPE_NONE = 2,
|
||||
};
|
||||
|
||||
enum HumanoidRigType
|
||||
{
|
||||
HUMANOID_RIG_TYPE_R6 = 0,
|
||||
HUMANOID_RIG_TYPE_R15 = 1,
|
||||
};
|
||||
private:
|
||||
friend unsigned int HUMAN::HumanoidState::checkComputeEvent(); // only used to check for exploits.
|
||||
|
||||
typedef DescribedCreatable<Humanoid, Instance, sHumanoid> Super;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// REFLECTED DATA
|
||||
shared_ptr<PartInstance> seatPart; // seat the humanoid is sitting in
|
||||
shared_ptr<PartInstance> walkToPart; // if null, then use the walk speed control
|
||||
Vector3 walkToPoint; // in part coordinate Frame
|
||||
Vector3 walkDirection; // x == xvalue, y == 0, z== zvalue
|
||||
Vector3 luaMoveDirection; // unit vector, used to move humanoid continously in that direction
|
||||
Vector3 rawMovementVector; // unit vector, stores the raw input (never world adjusted)
|
||||
Vector3 targetPoint;
|
||||
Vector3 replicatedTargetPoint;
|
||||
float walkAngleError;
|
||||
HeapValue<float> walkSpeed;
|
||||
HeapValue<float> walkSpeedShadow; // due to exploits.
|
||||
HeapValue<float> percentWalkSpeed; // used to make walk speed variable (for joysticks and the like)
|
||||
HeapValue<float> health;
|
||||
HeapValue<float> maxHealth;
|
||||
mutable ObscureValue<size_t> walkSpeedErrors; // only used in const member functions...
|
||||
HeapValue<float> jumpPower;
|
||||
HeapValue<float> maxSlopeAngle;
|
||||
HeapValue<float> hipHeight;
|
||||
bool torsoArrived;
|
||||
bool jump;
|
||||
bool autoJump;
|
||||
bool sit;
|
||||
bool touchedHard;
|
||||
bool strafe;
|
||||
bool localSimulating; // am I simulating this humanoid?
|
||||
bool ownedByLocalPlayer; // is this my own humanoid?
|
||||
bool typing;
|
||||
bool autorotate;
|
||||
HumanoidRigType rigType;
|
||||
HeapValue<bool> platformStanding;
|
||||
|
||||
bool autoJumpEnabled;
|
||||
|
||||
bool activatePhysics;
|
||||
Vector3 activatePhysicsImpulse; //
|
||||
|
||||
int ragdollCriteria;
|
||||
int numContacts; // Used to signal nearlyTouched event
|
||||
NameOcclusion nameOcclusion;
|
||||
HumanoidDisplayDistanceType displayDistanceType;
|
||||
float nameDisplayDistance;
|
||||
float healthDisplayDistance;
|
||||
Vector3 cameraOffset; // When this humanoid is used as a camera target, offset the camera target by this vector
|
||||
|
||||
bool isWalkingFromStudioTouchEmulation;
|
||||
|
||||
std::string displayText;
|
||||
ContentFilter::FilterResult filterState;
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// INTERNAL DATA
|
||||
// Controller interface - server side
|
||||
bool isWalking;
|
||||
double walkTimer;
|
||||
Vector3 getDeltaToGoal() const;
|
||||
void setWalkMode(bool walking);
|
||||
void stepWalkMode(double gameDt);
|
||||
|
||||
bool clickToWalkEnabled;
|
||||
|
||||
bool stateTransitionEnabled[HUMAN::NUM_STATE_TYPES];
|
||||
|
||||
Vector3 lastFloorNormal;
|
||||
// Humanoid Network Floor Platforms
|
||||
boost::shared_ptr<PartInstance> lastFloorPart;
|
||||
boost::shared_ptr<PartInstance> rootFloorMechPart;
|
||||
int lastFilterPhase;
|
||||
|
||||
// hack - easiest place to update is on query of had neck
|
||||
bool hadNeck; // has this humanoid ever had a neck? Only break joints on death if so
|
||||
bool hadHealth; // has this humanoid ever had health > 0? Only break joints on death if so
|
||||
|
||||
Vector3 pos0; // for looking for movement spikes
|
||||
Vector3 pos1;
|
||||
Vector3 pos2;
|
||||
|
||||
void updateHadHealth() {
|
||||
hadHealth = hadHealth || (health > 0.0f);
|
||||
}
|
||||
|
||||
typedef enum {TORSO, HEAD, RIGHT_ARM, LEFT_ARM, RIGHT_LEG, LEFT_LEG, VISIBLE_TORSO, APPENDAGE_COUNT} AppendageType;
|
||||
|
||||
shared_ptr<PartInstance> appendageCache[APPENDAGE_COUNT];
|
||||
shared_ptr<PartInstance> baseInstance;
|
||||
|
||||
rbx::signals::scoped_connection characterChildAdded;
|
||||
rbx::signals::scoped_connection characterChildRemoved;
|
||||
void onEvent_ChildModified(shared_ptr<Instance> child);
|
||||
|
||||
boost::unordered_map<shared_ptr<PartInstance>, rbx::signals::scoped_connection> siblingMap;
|
||||
void updateSiblingPropertyListener(shared_ptr<PartInstance> sibling);
|
||||
void onEvent_SiblingPropertyChanged(const RBX::Reflection::PropertyDescriptor* desc);
|
||||
|
||||
shared_ptr<StatusInstance> status;
|
||||
|
||||
rbx::signals::scoped_connection onCFrameChangedConnection;
|
||||
rbx::signals::scoped_connection humanoidEquipConnection;
|
||||
|
||||
void setCachePointerByType(AppendageType appendage, PartInstance *part);
|
||||
void updateBaseInstance();
|
||||
|
||||
const PartInstance* getConstAppendageSlow(AppendageType appendage) const;
|
||||
PartInstance* getAppendageFast(AppendageType appendage, shared_ptr<PartInstance>& appendagePart);
|
||||
PartInstance* getAppendageSlow(AppendageType appendage);
|
||||
|
||||
World* world;
|
||||
shared_ptr<HUMAN::HumanoidState> currentState;
|
||||
HUMAN::StateType previousState;
|
||||
|
||||
shared_ptr<Animator> animator;
|
||||
Animator* getAnimator();
|
||||
|
||||
void updateLocalSimulating(); // Do I need to simulate this humanoid?
|
||||
|
||||
void onLocalHumanoidEnteringWorkspace();
|
||||
|
||||
void onCFrameChangedFromReflection();
|
||||
|
||||
bool hasWalkToPoint(Vector3& worldPosition) const;
|
||||
|
||||
bool canClickToWalk() const;
|
||||
|
||||
void setLocalTransparencyModifier(float transparencyModifier) const;
|
||||
|
||||
void setWalkDirectionInternal(const Vector3& value, bool raiseSignal);
|
||||
void setJumpInternal(bool value, bool replicate);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Instance
|
||||
/*override*/ bool askSetParent(const Instance* instance) const;
|
||||
/*override*/ void onAncestorChanged(const AncestorChanged& event);
|
||||
/*override*/ void setName(const std::string& value);
|
||||
/*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider);
|
||||
/*override*/ void onDescendantAdded(Instance* instance);
|
||||
/*override*/ void onDescendantRemoving(const shared_ptr<Instance>& instance);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IAdornable
|
||||
/*override*/ bool shouldRender3dAdorn() const {return true;}
|
||||
/*override*/ bool shouldRender3dSortedAdorn() const {return true;}
|
||||
/*override*/ Vector3 render3dSortedPosition() const;
|
||||
/*override*/ void render3dAdorn(Adorn* adorn);
|
||||
/*override*/ void render3dSortedAdorn(Adorn* adorn);
|
||||
|
||||
void renderMultiplayer(Adorn* adorn, const RBX::Camera& camera);
|
||||
|
||||
void renderBillboard(Adorn* adorn, const RBX::Camera& camera);
|
||||
void renderBillboardImpl(Adorn* adorn, const Vector2& screenLoc, float fontSize, const Color3& nameTagColor, float nameAlpha, float healthAlpha);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// SteppedInstance
|
||||
/*override*/ void onStepped(const Stepped& event);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// KernelJoint / Connector
|
||||
/*override*/ void computeForce(bool throttling);
|
||||
/*override*/ Body* getEngineBody() {return getRootBodyFast();}
|
||||
/*override*/ virtual KernelType getConnectorKernelType() const { return Connector::HUMANOID; }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ILocation
|
||||
/*override*/ const CoordinateFrame getLocation();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CameraSubject
|
||||
/*override*/ const CoordinateFrame getRenderLocation();
|
||||
/*override*/ const Vector3 getRenderSize();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ICharacterSubject
|
||||
/*override*/ float getYAxisRotationalVelocity() const; // used for camera control
|
||||
/*override*/ void setFirstPersonRotationalVelocity(const Vector3& desiredLook, bool firstPersonOn);
|
||||
/*override*/ void getSelectionIgnorePrimitives(std::vector<const Primitive*>& primitives);
|
||||
/*override*/ virtual bool hasFocusCoord() const {return getHeadSlow() != NULL;}
|
||||
|
||||
// Humanoid Platform Networking
|
||||
bool validateNetworkUpdateDistance(PartInstance* floorPart, CoordinateFrame& previousFloorPosition, float& netDt);
|
||||
void truncateDisplacementIfObstacle(PartInstance* floorPart, Vector3& newCharPosition, const Vector3& previousCharPosition);
|
||||
Vector3 getSimulatedFrictionVelocityOffset(PartInstance* floorPart, Vector3& newCharPosition, const Vector3& previousCharPosition, const Vector3& charPosInFloorSpace, const RBX::Velocity& previousFloorVelocity, float& netDt);
|
||||
const Velocity getHumanoidRelativeVelocityToPart(Primitive* floorPrim);
|
||||
|
||||
public:
|
||||
void updateNetworkFloorPosition(PartInstance* floorPart, CoordinateFrame& previousFloorPosition, RBX::Velocity& lastFloorVelocity, float& netDt);
|
||||
bool shouldNotApplyFloorVelocity(Primitive* floorPrim);
|
||||
bool primitiveIsLastFloor(Primitive* prim);
|
||||
void updateFloorSimPhaseCharVelocity(Primitive* floorPrim);
|
||||
// End Humanoid Platform Networking
|
||||
|
||||
|
||||
/*override*/ void tellCameraNear(float distance) const;
|
||||
/*override*/ void tellCameraSubjectDidChange(shared_ptr<Instance> oldSubject, shared_ptr<Instance> newSubject) const;
|
||||
/*override*/ void tellCursorOver(float cursorOffset) const;
|
||||
/*override*/ void getCameraIgnorePrimitives(std::vector<const Primitive*>& primitives);
|
||||
/*override*/ Velocity calcDesiredWalkVelocity() const; // used for camera control
|
||||
|
||||
static float autoTurnSpeed() {return 8.0f;}
|
||||
|
||||
Humanoid();
|
||||
~Humanoid();
|
||||
|
||||
bool waitingForTorso() { return !torsoArrived; }
|
||||
bool isLegalForClientToChange(const Reflection::PropertyDescriptor& desc) const;
|
||||
int getPlayerId();
|
||||
|
||||
enum Status
|
||||
{
|
||||
POISON_STATUS = 0,
|
||||
CONFUSION_STATUS = 1,
|
||||
};
|
||||
bool hasStatus(Status status);
|
||||
bool addStatus(Status status);
|
||||
bool removeStatus(Status status);
|
||||
bool hasCustomStatus(std::string status);
|
||||
bool addCustomStatus(std::string status);
|
||||
bool removeCustomStatus(std::string status);
|
||||
bool isLocalSimulating() const {return localSimulating;}
|
||||
bool computeNearlyTouched();
|
||||
|
||||
bool getStateTransitionEnabled(HUMAN::StateType state);
|
||||
void setStateTransitionEnabled(HUMAN::StateType state, bool enabled);
|
||||
|
||||
shared_ptr<const Reflection::ValueArray> getStatuses();
|
||||
rbx::signal<void(Status)> statusAddedSignal;
|
||||
rbx::signal<void(Status)> statusRemovedSignal;
|
||||
rbx::signal<void(std::string)> customStatusAddedSignal;
|
||||
rbx::signal<void(std::string)> customStatusRemovedSignal;
|
||||
|
||||
rbx::remote_signal<void(shared_ptr<Instance>)> serverEquipToolSignal;
|
||||
|
||||
// Humanoid Network Update Connection
|
||||
rbx::signals::scoped_connection onPositionUpdatedByNetworkConnection;
|
||||
|
||||
NameOcclusion getNameOcclusion() const { return nameOcclusion; }
|
||||
void setNameOcclusion(NameOcclusion value);
|
||||
|
||||
HumanoidDisplayDistanceType getDisplayDistanceType() const { return displayDistanceType; }
|
||||
void setDisplayDistanceType(HumanoidDisplayDistanceType value);
|
||||
|
||||
static Humanoid* humanoidFromBodyPart(Instance* bodyPart);
|
||||
static const Humanoid* constHumanoidFromBodyPart(const Instance* bodyPart);
|
||||
static const Humanoid* constHumanoidFromDescendant(const Instance* bodyPart);
|
||||
|
||||
static Humanoid* modelIsCharacter(Instance* testModel);
|
||||
static const Humanoid* modelIsConstCharacter(const Instance* testModel);
|
||||
|
||||
static Humanoid* getLocalHumanoidFromContext(Instance* context);
|
||||
static const Humanoid* getConstLocalHumanoidFromContext(const Instance* context);
|
||||
|
||||
static PartInstance* getLocalHeadFromContext(Instance* context);
|
||||
static const PartInstance* getConstLocalHeadFromContext(const Instance* context);
|
||||
|
||||
static ModelInstance* getCharacterFromHumanoid(Humanoid* humanoid);
|
||||
static const ModelInstance* getConstCharacterFromHumanoid(const Humanoid* humanoid);
|
||||
|
||||
static PartInstance* getHeadFromCharacter(ModelInstance* character);
|
||||
static const PartInstance* getConstHeadFromCharacter(const ModelInstance* character);
|
||||
|
||||
static Weld* getGrip(Instance* character);
|
||||
|
||||
static const Vector3 &defaultCharacterCorner() { static Vector3 corner(2.5f,2.5f,2.5f); return corner; }
|
||||
|
||||
// By Definition, these are all called by HumanoidState - these are reflected
|
||||
rbx::signal<void()> diedSignal;
|
||||
rbx::signal<void(float)> swimmingSignal;
|
||||
rbx::signal<void(float)> runningSignal; // state change scripts
|
||||
rbx::signal<void(float)> climbingSignal; // state change scripts
|
||||
rbx::signal<void(bool)> jumpingSignal; // state change scripts
|
||||
rbx::signal<void(bool)> freeFallingSignal;
|
||||
rbx::signal<void(bool)> strafingSignal;
|
||||
rbx::signal<void(bool)> gettingUpSignal;
|
||||
rbx::signal<void(bool)> fallingDownSignal;
|
||||
rbx::signal<void(bool)> ragdollSignal;
|
||||
rbx::signal<void(bool, shared_ptr<Instance>)> seatedSignal;
|
||||
rbx::signal<void(bool)> platformStandingSignal;
|
||||
rbx::signal<void(RBX::HUMAN::StateType, RBX::HUMAN::StateType)> stateChangedSignal;
|
||||
rbx::signal<void(RBX::HUMAN::StateType, bool)> stateEnabledChangedSignal;
|
||||
RBX::HUMAN::StateType getCurrentStateType();
|
||||
RBX::HUMAN::StateType getPreviousStateType() { return previousState; };
|
||||
void setPreviousStateType(RBX::HUMAN::StateType newState);
|
||||
void changeState(RBX::HUMAN::StateType state);
|
||||
static bool isStateInString(const std::string& text, const RBX::HUMAN::StateType &compare, RBX::HUMAN::StateType& value);
|
||||
|
||||
rbx::signal<void(float)> healthChangedSignal;
|
||||
|
||||
// Internal use only - no reflection - happens both client, server
|
||||
rbx::signal<void()> doneSittingSignal;
|
||||
rbx::signal<void()> donePlatformStandingSignal;
|
||||
|
||||
void equipToolInstance(shared_ptr<Instance> instance);
|
||||
void equipTool(RBX::Tool* tool);
|
||||
void unequipTools();
|
||||
|
||||
void setWalkSpeed(float value);
|
||||
float getWalkSpeed() const {return walkSpeed;}
|
||||
void testWalkSpeed(float walkSpeed, float percentWalkSpeed) const
|
||||
{
|
||||
walkSpeedErrors = (walkSpeed > walkSpeedShadow) ? walkSpeedErrors + 1 : 0;
|
||||
if (walkSpeedErrors > 8)
|
||||
{
|
||||
RBX::Security::setHackFlagVs<LINE_RAND4>(RBX::Security::hackFlag11, HATE_SPEEDHACK);
|
||||
}
|
||||
if (fabs(percentWalkSpeed) > 1.01)
|
||||
{
|
||||
RBX::Security::setHackFlagVs<LINE_RAND4>(RBX::Security::hackFlag11, HATE_SPEEDHACK);
|
||||
}
|
||||
}
|
||||
|
||||
void setPercentWalkSpeed(float value);
|
||||
float getPercentWalkSpeed() const { return percentWalkSpeed; }
|
||||
|
||||
void setJumpPower(float value);
|
||||
float getJumpPower() const { return jumpPower; }
|
||||
|
||||
void setMaxSlopeAngle(float value);
|
||||
float getMaxSlopeAngle() const { return maxSlopeAngle; }
|
||||
|
||||
const Vector3 &getLastFloorNormal() const { return lastFloorNormal; }
|
||||
void setLastFloorNormal(const Vector3 &norm) { lastFloorNormal = norm; }
|
||||
|
||||
void setHipHeight(float value);
|
||||
float getHipHeight() const { return hipHeight; }
|
||||
|
||||
// Health / damage interface
|
||||
void setHealth(float value);
|
||||
void setHealthUi(float value);
|
||||
void zeroHealthLocal() {health = 0.0f;} // for a non-simulating client -zero out health without bouncing back to the server
|
||||
float getHealth() const {return health;}
|
||||
|
||||
void setMaxHealth(float value);
|
||||
float getMaxHealth() const {return maxHealth;}
|
||||
|
||||
void setTyping(bool value) { typing = value; }
|
||||
bool getTyping() const { return typing; }
|
||||
|
||||
void takeDamage(float value); // honors explosions, etc.
|
||||
|
||||
void setClickToWalkEnabled(bool value) { clickToWalkEnabled = value; }
|
||||
|
||||
// Controller interface - don't set the walk direction directly
|
||||
void setWalkDirection(const Vector3& value); // compacted - z is in the y place
|
||||
Vector3 getWalkDirection() const {return walkDirection;} // compacted - z is in the y place
|
||||
bool allow3dWalkDirection() const;
|
||||
|
||||
void move(Vector3 walkVector, bool relativeToCamera);
|
||||
|
||||
Vector3 getLuaMoveDirection() const { return luaMoveDirection;}
|
||||
void setLuaMoveDirection(const Vector3& value);
|
||||
Vector3 getRawMovementVector() const { return rawMovementVector; }
|
||||
|
||||
bool getAutoJumpEnabled() const { return autoJumpEnabled; };
|
||||
void setAutoJumpEnabled(bool value);
|
||||
|
||||
void setWalkAngleError(const float &value);
|
||||
float getWalkAngleError() const {return walkAngleError;}
|
||||
|
||||
void setWalkToPoint(const Vector3& value);
|
||||
const Vector3& getWalkToPoint() const {return walkToPoint;}
|
||||
|
||||
void setWalkToPart(PartInstance* value);
|
||||
PartInstance* getWalkToPart() const {return walkToPart.get();}
|
||||
|
||||
void setSeatPart(PartInstance* value);
|
||||
PartInstance* getSeatPart() const {return seatPart.get();}
|
||||
|
||||
void setJump(bool value);
|
||||
bool getJump() const { return jump; }
|
||||
|
||||
void setAutoJump(bool value);
|
||||
bool getAutoJump() const { return autoJump;}
|
||||
|
||||
void setSit(bool value);
|
||||
bool getSit() const { return sit; }
|
||||
|
||||
void setAutoRotate(bool value);
|
||||
bool getAutoRotate() const { return autorotate; }
|
||||
|
||||
void setTouchedHard(bool hit) { touchedHard = hit; }
|
||||
|
||||
void setActivatePhysics(bool flag, const Vector3& impulse)
|
||||
{
|
||||
activatePhysics = flag;
|
||||
if (flag)
|
||||
activatePhysicsImpulse += impulse;
|
||||
else
|
||||
activatePhysicsImpulse = impulse;
|
||||
}
|
||||
bool getActivatePhysics() { return activatePhysics; }
|
||||
const Vector3 getActivatePhysicsImpulse() { return activatePhysicsImpulse; }
|
||||
bool getTouchedHard() { return touchedHard; }
|
||||
|
||||
void setRagdollCriteria(int value);
|
||||
int getRagdollCriteria() const { return ragdollCriteria; }
|
||||
|
||||
void setPlatformStanding(bool value);
|
||||
bool getPlatformStanding() const { return platformStanding; }
|
||||
|
||||
void setStrafe(bool value);
|
||||
bool getStrafe() const { return strafe; }
|
||||
|
||||
bool getDead() const;
|
||||
|
||||
void setHadNeck() {hadNeck = true;}
|
||||
bool breakJointsOnDeath() const {return hadNeck && hadHealth;}
|
||||
|
||||
void setTargetPoint(const Vector3& value);
|
||||
void setTargetPointLocal(const Vector3& value); // does not replicate
|
||||
const Vector3& getTargetPoint() const {return targetPoint;}
|
||||
|
||||
void setNameDisplayDistance(float d);
|
||||
float getNameDisplayDistance() const { return nameDisplayDistance; }
|
||||
|
||||
void setHealthDisplayDistance(float d);
|
||||
float getHealthDisplayDistance() const { return healthDisplayDistance; }
|
||||
|
||||
void setCameraOffset(const Vector3 &value);
|
||||
const Vector3 &getCamearaOffset() const { return cameraOffset; }
|
||||
|
||||
// Humanoid Platform Update Getters and Setters;
|
||||
void setLastFloor(PartInstance* part)
|
||||
{
|
||||
if(lastFloorPart)
|
||||
{
|
||||
lastFloorPart.reset();
|
||||
}
|
||||
lastFloorPart = shared_from(part);
|
||||
}
|
||||
const shared_ptr<PartInstance>& getLastFloor() const { return lastFloorPart; }
|
||||
|
||||
void setRootFloorPart(PartInstance* part)
|
||||
{
|
||||
if (rootFloorMechPart)
|
||||
{
|
||||
rootFloorMechPart.reset();
|
||||
}
|
||||
rootFloorMechPart = shared_from(part);
|
||||
}
|
||||
shared_ptr<PartInstance> getRootFloorPart() const { return rootFloorMechPart; }
|
||||
|
||||
int getCurrentFloorFilterPhase();
|
||||
int getCurrentFloorFilterPhase(Assembly* floorAssembly);
|
||||
|
||||
void setLastFloorPhase(int phase) { lastFilterPhase = phase; }
|
||||
int getLastFloorPhase() const { return lastFilterPhase; }
|
||||
|
||||
// Walk Utilities
|
||||
void moveTo(const Vector3& worldPosition, PartInstance* part);
|
||||
void moveTo2(Vector3 worldPosition, shared_ptr<Instance> part);
|
||||
rbx::signal<void(bool)> moveToFinishedSignal;
|
||||
|
||||
bool getUseR15() const { return (rigType != HUMANOID_RIG_TYPE_R6); }
|
||||
Humanoid::HumanoidRigType getRigType() const { return rigType; }
|
||||
void setRigType(Humanoid::HumanoidRigType type);
|
||||
|
||||
// Build Joints
|
||||
void buildJoints(RBX::DataModel* dm = NULL);
|
||||
void buildJointsFromAttachments(PartInstance* part, std::vector<PartInstance*>& characterParts);
|
||||
|
||||
JointInstance* getRightShoulder();
|
||||
Joint* getNeck();
|
||||
|
||||
// Primitive
|
||||
void getPrimitives(std::vector<Primitive*>& primitives) const;
|
||||
|
||||
void getParts(std::vector<PartInstance*>& primitives) const;
|
||||
|
||||
PartInstance* getTorsoDangerous() const; // reflection only
|
||||
PartInstance* getLeftLegDangerous() const; // reflection only
|
||||
PartInstance* getRightLegDangerous() const; // reflection only
|
||||
|
||||
// TODO: No internal buffering - after refactor, rename without the word slow
|
||||
PartInstance* getTorsoSlow(); // no internal buffering
|
||||
PartInstance* getVisibleTorsoSlow();
|
||||
PartInstance* getHeadSlow();
|
||||
PartInstance* getLeftLegSlow();
|
||||
PartInstance* getRightLegSlow();
|
||||
PartInstance* getLeftArmSlow();
|
||||
PartInstance* getRightArmSlow();
|
||||
StatusInstance* getStatusSlow();
|
||||
|
||||
const PartInstance* getTorsoSlow() const; // no internal buffering
|
||||
const PartInstance* getVisibleTorsoSlow() const;
|
||||
const PartInstance* getHeadSlow() const;
|
||||
const PartInstance* getLeftLegSlow() const;
|
||||
const PartInstance* getRightLegSlow() const;
|
||||
const PartInstance* getLeftArmSlow() const;
|
||||
const PartInstance* getRightArmSlow() const;
|
||||
const StatusInstance* getStatusSlow() const;
|
||||
|
||||
Primitive* getTorsoPrimitiveSlow();
|
||||
Primitive* getHeadPrimitiveSlow();
|
||||
|
||||
// Internal buffering
|
||||
PartInstance* getTorsoFast();
|
||||
PartInstance* getVisibleTorsoFast();
|
||||
PartInstance* getHeadFast();
|
||||
PartInstance* getLeftLegFast();
|
||||
PartInstance* getRightLegFast();
|
||||
PartInstance* getLeftArmFast();
|
||||
PartInstance* getRightArmFast();
|
||||
StatusInstance* getStatusFast();
|
||||
|
||||
Primitive* getTorsoPrimitiveFast();
|
||||
|
||||
// Body
|
||||
inline Body* getTorsoBodyFast()
|
||||
{
|
||||
Primitive* prim = getTorsoPrimitiveFast();
|
||||
return prim ? prim->getBody() : NULL;
|
||||
}
|
||||
Body* getRootBodyFast();
|
||||
|
||||
// Attachment Points
|
||||
CoordinateFrame getTopOfHead() const;
|
||||
CoordinateFrame getRightArmGrip() const;
|
||||
|
||||
float getTorsoHeading() const; // 0 == North == -Z. Pi/2 = WEST == -x
|
||||
float getTorsoElevation() const;
|
||||
|
||||
void setTorso(PartInstance* value);
|
||||
void setLeftLeg(PartInstance* value);
|
||||
void setRightLeg(PartInstance* value);
|
||||
|
||||
void setHeadMesh(DataModelMesh* value);
|
||||
void setHeadDecal(Decal* value);
|
||||
|
||||
World* getWorld() {return world;};
|
||||
const World* getConstWorld() const {return world;};
|
||||
|
||||
static void renderWaypoint(Adorn* adorn, const Vector3& waypoint);
|
||||
|
||||
// proxy interface to Animator object.
|
||||
shared_ptr<Instance> loadAnimation(shared_ptr<Instance> animation);
|
||||
bool CheckTorso();
|
||||
void setupAnimator();
|
||||
shared_ptr<const Reflection::ValueArray> getPlayingAnimationTracks();
|
||||
|
||||
rbx::signal<void(shared_ptr<Instance>)> animationPlayedSignal;
|
||||
|
||||
bool getOwnedByLocalPlayer() const { return ownedByLocalPlayer; }
|
||||
|
||||
bool getWalkingFromStudioTouchEmulation() const { return isWalkingFromStudioTouchEmulation; }
|
||||
void setWalkingFromStudioTouchEmulation(bool value) { isWalkingFromStudioTouchEmulation = value; }
|
||||
};
|
||||
|
||||
} // namespace RBX
|
||||
@@ -0,0 +1,346 @@
|
||||
/* Copyright 2003-2007 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Util/HitTestFilter.h"
|
||||
#include "GfxBase/IAdornable.h"
|
||||
#include "Util/Name.h"
|
||||
#include "rbx/Debug.h"
|
||||
#include "Util/Velocity.h"
|
||||
#include "rbx/boost.hpp"
|
||||
#include "Reflection/Event.h"
|
||||
#include "G3D/Array.h"
|
||||
#include "util/PartMaterial.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define CHARACTER_FORCE_DEBUG 0
|
||||
|
||||
namespace RBX
|
||||
{
|
||||
class Humanoid;
|
||||
class PartInstance;
|
||||
class Controller;
|
||||
class Assembly;
|
||||
class GeometryService;
|
||||
|
||||
namespace HUMAN
|
||||
{
|
||||
typedef enum { FALLING_DWN = 0,
|
||||
RAGDOLL, // 1
|
||||
GETTING_UP,
|
||||
JUMPING,
|
||||
SWIMMING,
|
||||
FREE_FALL, // 4: balancing, no thrust
|
||||
FLYING,
|
||||
LANDED, // 6: can't jump
|
||||
RUNNING, // 7
|
||||
RUNNING_SLAVE, // 8: slave side - lock to running mode to do accurate physics when touched slave side
|
||||
RUNNING_NO_PHYS, // 9
|
||||
STRAFING_NO_PHYS,
|
||||
CLIMBING,
|
||||
SEATED,
|
||||
PLATFORM_STANDING,
|
||||
DEAD,
|
||||
PHYSICS,
|
||||
NUM_STATE_TYPES,
|
||||
xx } StateType; // XX == NO change
|
||||
|
||||
typedef enum { NO_HEALTH = 0, // Humanoid Commands
|
||||
NO_NECK,
|
||||
JUMP_CMD,
|
||||
STRAFE_CMD,
|
||||
NO_STRAFE_CMD,
|
||||
SIT_CMD,
|
||||
NO_SIT_CMD,
|
||||
PLATFORM_STAND_CMD,
|
||||
NO_PLATFORM_STAND_CMD,
|
||||
TIPPED, // Tilting
|
||||
UPRIGHT,
|
||||
FACE_LDR, // Ladder
|
||||
AWAY_LDR,
|
||||
OFF_FLOOR, // Floor
|
||||
OFF_FLOOR_GRACE, // Floor w/ Grace Period
|
||||
ON_FLOOR,
|
||||
TOUCHED, // Other Objects
|
||||
NEARLY_TOUCHED, // Other Objects
|
||||
TOUCHED_HARD,
|
||||
ACTIVATE_PHYSICS,
|
||||
FINISHED,
|
||||
TIMER_UP, // FINISHED_FALLING, READY_TO_JUMP,
|
||||
NO_TOUCH_ONE_SECOND,
|
||||
HAS_GYRO,
|
||||
HAS_BUOYANCY,
|
||||
NO_BUOYANCY,
|
||||
NUM_EVENT_TYPES } EventType;
|
||||
|
||||
#if CHARACTER_FORCE_DEBUG
|
||||
class DebugRay
|
||||
{
|
||||
public:
|
||||
RbxRay ray;
|
||||
Color3 color;
|
||||
|
||||
DebugRay(const RbxRay& _ray, const Color3& _color)
|
||||
{
|
||||
ray = _ray;
|
||||
color = _color;
|
||||
}
|
||||
|
||||
void Draw(Adorn* adorn);
|
||||
};
|
||||
#endif
|
||||
|
||||
class HumanoidState : public INamed,
|
||||
public HitTestFilter
|
||||
|
||||
{
|
||||
public:
|
||||
static const unsigned int kCorrectCheckValue = 2;
|
||||
|
||||
private:
|
||||
const Vector3& unitializedFloorTouch() const {
|
||||
static Vector3 v(1e15f, 1e15f, 1e15f);
|
||||
return v;
|
||||
}
|
||||
|
||||
Humanoid* humanoid;
|
||||
float timer;
|
||||
float noTouchTimer;
|
||||
bool nearlyTouched;
|
||||
bool shouldRender;
|
||||
bool finished;
|
||||
bool outOfWater;
|
||||
bool headClear;
|
||||
StateType priorState;
|
||||
StateType luaState;
|
||||
|
||||
G3D::Array<PartInstance*> foundParts; // temp buffer
|
||||
bool facingLadder;
|
||||
shared_ptr<PartInstance> floorPart;
|
||||
PartMaterial floorMaterial;
|
||||
Vector3 floorTouchInWorld;
|
||||
Vector3 floorTouchNormal;
|
||||
Vector3 floorHumanoidLocationInWorld;
|
||||
float noFloorTimer;
|
||||
|
||||
// Cut down firing of the running event to when there are major difference in velocity
|
||||
float lastMovementVelocity;
|
||||
|
||||
// signals that the state needs these updated
|
||||
bool usesEvent(EventType e) const;
|
||||
bool usesLadder() const {return (usesEvent(FACE_LDR) || usesEvent(AWAY_LDR));}
|
||||
bool usesFloor() const {return (usesEvent(OFF_FLOOR) || usesEvent(ON_FLOOR) || usesEvent(OFF_FLOOR_GRACE));}
|
||||
|
||||
float computeTilt() const;
|
||||
bool computeTipped() const;
|
||||
bool computeUpright() const;
|
||||
bool computeHasGyro() const;
|
||||
bool computeJumped() const;
|
||||
float computeFloorTilt() const;
|
||||
|
||||
void setLegsCanCollide(bool canCollide);
|
||||
void setArmsCanCollide(bool canCollide);
|
||||
void setHeadCanCollide(bool canCollide);
|
||||
void setTorsoCanCollide(bool canCollide);
|
||||
|
||||
int ladderCheck;
|
||||
virtual int ladderCheckRate() { return 2; }
|
||||
bool findPrimitiveInLadderZone(Adorn* adorn);
|
||||
bool findLadder(Adorn* adorn);
|
||||
void doLadderRaycast(GeometryService *geom, const RbxRay& caster,Humanoid* humanoid, Primitive** hitPrimOut,
|
||||
Vector3* hitLocationOut);
|
||||
void doAutoJump();
|
||||
void findFloor(shared_ptr<PartInstance>& oldFloor);
|
||||
shared_ptr<PartInstance> tryFloor(const RbxRay& ray, Vector3& hitLocation, Vector3& hitNormal, float maxDistance, Assembly* humanoidAssembly, PartMaterial& recentFloorMaterial);
|
||||
void AverageFloorRayCast(shared_ptr<PartInstance> &floorPart, Vector3& floorPartHitLocation, Vector3& floorPartHitNormal,
|
||||
PartMaterial& floorPartHitMaterial, Vector3& hitLocationAccumulator, int& hitLocationCount, const bool UpdateFloorPart,
|
||||
const Vector3& offset, const float maxDistance, Assembly* humanoidAssembly, const CoordinateFrame& torsoC);
|
||||
void preStepFloor();
|
||||
void preStepCollide();
|
||||
void preStepSimulatorSide(float dt);
|
||||
void preStepSlaveSide() {preStepCollide();}
|
||||
|
||||
static void doSimulatorStateTable(shared_ptr<HumanoidState>& state, float dt);
|
||||
static void doSlaveStateTable(shared_ptr<HumanoidState>& state, StateType newType);
|
||||
static HumanoidState* create(StateType newType, StateType oldType, Humanoid* humanoid);
|
||||
static HumanoidState* createNew(StateType newType, StateType oldType, Humanoid* humanoid);
|
||||
static void changeState(shared_ptr<HumanoidState>& state, StateType newType);
|
||||
|
||||
void fireEvent(StateType stateType, bool entering);
|
||||
|
||||
// Override hitTestFiler
|
||||
/*override*/ Result filterResult(const Primitive* testMe) const;
|
||||
|
||||
protected:
|
||||
|
||||
// For debugging
|
||||
Vector3 maxTorque;
|
||||
Vector3 maxForce;
|
||||
float maxContactVel;
|
||||
Vector3 lastTorque;
|
||||
Vector3 lastForce;
|
||||
float lastContactVel;
|
||||
|
||||
static float minMoveVelocity() {return 0.5f;}
|
||||
static float maxClimbDistance() {return 2.45f;} // studs
|
||||
static const Vector3 maxMoveForce() {static Vector3 m(1000.0f, 10000.0f, 1000.0f); return m;} //const Vector3 maxMoveAccelerationGrid(5e4f*0.02f, 5e5f*0.02f, 1e4f*0.02f);
|
||||
static const Vector3 minMoveForce() {static Vector3 m(-1000.0f, 0.0f, -1000.0f); return m;}
|
||||
static const Vector3 maxSwimmingMoveForce() {static Vector3 m(10000.0f, 1000.0f, 10000.0f); return m;}
|
||||
static const Vector3 minSwimmingMoveForce() {static Vector3 m(-10000.0f, -10000.0f, -10000.0f); return m;}
|
||||
static float fallDelay() { return 0.125f; }
|
||||
static float maxLinearMoveForce() { return 143.0; }
|
||||
|
||||
// Need public for some Physics calculations outside of Humanoid State
|
||||
public:
|
||||
float steepSlopeAngle() const;
|
||||
static float runningKMoveP();
|
||||
static float runningKMovePForPGS();
|
||||
static float maxLinearGroundMoveForce() { return 500.0; }
|
||||
|
||||
protected:
|
||||
Assembly* filteringAssembly;
|
||||
|
||||
bool computeEvent(EventType eventType);
|
||||
|
||||
bool computeTouched();
|
||||
bool computeNearlyTouched();
|
||||
bool computeTouchedByMySimulation();
|
||||
bool computeTouchedHard();
|
||||
bool computeActivatePhysics();
|
||||
|
||||
void setOutOfWater() { outOfWater = true; }
|
||||
bool getOutOfWater() const { return outOfWater; }
|
||||
|
||||
void setTimer(float time) {timer = time;}
|
||||
float getTimer() const {return timer;}
|
||||
|
||||
bool getFinished() const {return finished;}
|
||||
void setFinished(bool value) {finished = value;}
|
||||
|
||||
bool getFacingLadder() const {return facingLadder;}
|
||||
bool getHeadClear() const { return headClear; }
|
||||
|
||||
PartMaterial getFloorMaterial() const { return floorMaterial; }
|
||||
float getFloorFrictionProperty(Primitive* floorPrim) const;
|
||||
|
||||
Primitive* getFloorPrimitive();
|
||||
const Primitive* getFloorPrimitiveConst() const;
|
||||
const Vector3& getFloorTouchInWorld() const {
|
||||
RBXASSERT(floorTouchInWorld != unitializedFloorTouch());
|
||||
return floorTouchInWorld;
|
||||
}
|
||||
const Vector3& getFloorTouchNormal() const {
|
||||
RBXASSERT(floorTouchInWorld != unitializedFloorTouch());
|
||||
return floorTouchNormal;
|
||||
}
|
||||
const Vector3& getFloorHumanoidLocationInWorld() const {
|
||||
RBXASSERT(floorHumanoidLocationInWorld != unitializedFloorTouch());
|
||||
return floorHumanoidLocationInWorld;
|
||||
}
|
||||
|
||||
|
||||
const Velocity getFloorPointVelocity();
|
||||
Vector3 getRelativeMovementVelocity();
|
||||
float getDesiredAltitude() const;
|
||||
|
||||
#if CHARACTER_FORCE_DEBUG
|
||||
std::vector<DebugRay> debugRayList;
|
||||
#endif
|
||||
|
||||
void fireMovementSignal(rbx::signal<void(float)>& movementSignal, float movementVelocity);
|
||||
|
||||
// Tick Count - 30 FPS, state table occurs here
|
||||
virtual void onComputeForceImpl() = 0;
|
||||
virtual void onStepImpl() {}
|
||||
virtual void onSimulatorStepImpl(float stepDt) {}
|
||||
|
||||
protected:
|
||||
void setCanThrottleState(bool canThrottle); // only the Seated state can throttle - its joined to parts so it must
|
||||
|
||||
// Attributes moved in assemblies
|
||||
Assembly* getAssembly();
|
||||
const Assembly* getAssemblyConst() const;
|
||||
void stateToAssembly();
|
||||
StateType stateFromAssembly();
|
||||
|
||||
public:
|
||||
virtual bool armsShouldCollide() const {return true;}
|
||||
virtual bool legsShouldCollide() const {return true;}
|
||||
virtual bool headShouldCollide() const {return true;}
|
||||
virtual bool torsoShouldCollide() const {return true;}
|
||||
|
||||
virtual bool enableAutoJump() const { return true; }
|
||||
|
||||
virtual void onCFrameChangedFromReflection() { preStepFloor();} // recalculate floor part
|
||||
|
||||
|
||||
HumanoidState(Humanoid* humanoid, StateType priorState);
|
||||
|
||||
virtual ~HumanoidState();
|
||||
|
||||
const Humanoid* getHumanoidConst() const;
|
||||
|
||||
Humanoid* getHumanoid() {
|
||||
return const_cast<Humanoid*>(getHumanoidConst());
|
||||
}
|
||||
|
||||
static HumanoidState* defaultState(Humanoid* humanoid); // new Running(this));
|
||||
|
||||
static void simulate(shared_ptr<HumanoidState>& state, float dt);
|
||||
|
||||
static void updateHumanoidFloorStatus(shared_ptr<HumanoidState>& state);
|
||||
|
||||
static bool hasFloorChanged(shared_ptr<HumanoidState>& state, Primitive* lastFloorPrim);
|
||||
|
||||
static void noSimulate(shared_ptr<HumanoidState>& state); // for non-simulating humanoids, match states
|
||||
|
||||
virtual void fireEvents();
|
||||
|
||||
virtual float getYAxisRotationalVelocity() const {return 0.0f;}
|
||||
|
||||
float getCharacterHipHeight() const;
|
||||
|
||||
void onComputeForce();
|
||||
|
||||
bool torsoHasBuoyancy, leftLegHasBuoyancy, rightLegHasBuoyancy;
|
||||
std::vector<rbx::signals::connection> buoyancyConnections;
|
||||
void setTorsoHasBuoyancy( bool value ) { torsoHasBuoyancy = value; }
|
||||
void setLeftLegHasBuoyancy( bool value ) { leftLegHasBuoyancy = value; }
|
||||
void setRightLegHasBuoyancy( bool value ) { rightLegHasBuoyancy = value; }
|
||||
bool computeHasBuoyancy();
|
||||
|
||||
virtual StateType getStateType() const = 0;
|
||||
|
||||
void setLuaState(StateType state);
|
||||
StateType getLuaState() { return luaState; }
|
||||
|
||||
static const char *getStateNameByType(StateType state);
|
||||
|
||||
bool computeHitByHighImpactObject();
|
||||
|
||||
// only in debug
|
||||
void render3dAdorn(Adorn* adorn);
|
||||
|
||||
void setNearlyTouched();
|
||||
|
||||
// for security purposes, get the address of this code.
|
||||
// A member function pointer is a compiler defined data structure.
|
||||
static inline const void* getComputeEventBaseAddress()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
bool (RBX::HUMAN::HumanoidState::* hsce)(EventType) = &computeEvent;
|
||||
if(sizeof(hsce) == 8 || sizeof(hsce) == 4)
|
||||
{
|
||||
return (const void*&)(hsce); // odd, but required syntax for this horrible conversion.
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned int checkComputeEvent(); // this was added due to exploits.
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace RBX
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/Flying.h"
|
||||
|
||||
namespace RBX {
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sJumping;
|
||||
|
||||
class Jumping : public Named<Flying, sJumping>
|
||||
{
|
||||
private:
|
||||
typedef Named<Flying, sJumping> Super;
|
||||
/*override*/ StateType getStateType() const {return JUMPING;}
|
||||
|
||||
// Humanoid::State
|
||||
/*override*/ void onComputeForceImpl();
|
||||
|
||||
/*override*/ bool armsShouldCollide() const {return false;}
|
||||
/*override*/ bool legsShouldCollide() const {return false;}
|
||||
/*override*/ bool torsoShouldCollide() const {return false;}
|
||||
|
||||
// Override hitTestFiler
|
||||
/*override*/ Result filterResult(const Primitive* testMe) const;
|
||||
|
||||
bool findCeiling();
|
||||
shared_ptr<PartInstance> tryCeiling(const RbxRay& ray, float maxDistance, Assembly* humanoidAssembly);
|
||||
|
||||
Vector3 jumpDir;
|
||||
|
||||
public:
|
||||
Jumping(Humanoid* humanoid, StateType priorState);
|
||||
|
||||
static float kJumpP() {return 500.0f;}
|
||||
static float kJumpVelocityGrid() {return 50.0f;}
|
||||
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/HumanoidState.h"
|
||||
#include "V8World/Mechanism.h"
|
||||
|
||||
namespace RBX {
|
||||
class Assembly;
|
||||
class PhysicsService;
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sMovingNoPhysicsBase;
|
||||
|
||||
class MovingNoPhysicsBase
|
||||
: public Named<HumanoidState, sMovingNoPhysicsBase>
|
||||
{
|
||||
private:
|
||||
typedef Named<HumanoidState, sMovingNoPhysicsBase> Super;
|
||||
/*override*/ StateType getStateType() const {return RUNNING_NO_PHYS;}
|
||||
/*override*/ void fireEvents();
|
||||
|
||||
shared_ptr<PartInstance> torsoPart;
|
||||
weak_ptr<PhysicsService> physicsService;
|
||||
|
||||
rbx::signals::scoped_connection torsoAncestryChanged;
|
||||
void onEvent_TorsoAncestryChanged();
|
||||
void disconnectTorso();
|
||||
|
||||
const Assembly* getAssemblyConst() const;
|
||||
|
||||
void applyImpulseToFloor(float dt);
|
||||
|
||||
protected:
|
||||
|
||||
// Humanoid::State
|
||||
/*override*/ void onSimulatorStepImpl(float stepDt);
|
||||
/*override*/ void onComputeForceImpl();
|
||||
|
||||
/*override*/ bool armsShouldCollide() const {return false;}
|
||||
/*override*/ bool legsShouldCollide() const {return false;}
|
||||
/*override*/ bool headTorsoShouldCollide() const {return false;}
|
||||
|
||||
public:
|
||||
MovingNoPhysicsBase(Humanoid* humanoid, StateType priorState);
|
||||
~MovingNoPhysicsBase();
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
@@ -0,0 +1,30 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/Balancing.h"
|
||||
#include "Util/Name.h"
|
||||
|
||||
namespace RBX {
|
||||
namespace HUMAN {
|
||||
|
||||
// Flying occurs when there's no ground below you. You have the ability
|
||||
// to turn around the y-axis, but not much else.
|
||||
extern const char* const sRagdoll;
|
||||
|
||||
class Ragdoll : public Named<HumanoidState, sRagdoll>
|
||||
{
|
||||
private:
|
||||
typedef Named<HumanoidState, sRagdoll> Super;
|
||||
/*override*/ StateType getStateType() const {return RAGDOLL;}
|
||||
/*override*/ void onStepImpl();
|
||||
/*override*/ void onComputeForceImpl() {}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
public:
|
||||
Ragdoll(Humanoid* humanoid, StateType priorState);
|
||||
~Ragdoll();
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/RunningBase.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
class Body;
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sRunning;
|
||||
extern const char* const sRunningSlave;
|
||||
extern const char* const sLanded;
|
||||
extern const char* const sClimbing;
|
||||
|
||||
|
||||
class Running : public Named<RunningBase, sRunning>
|
||||
{
|
||||
private:
|
||||
typedef Named<RunningBase, sRunning> Super;
|
||||
/*override*/ StateType getStateType() const {return RUNNING;}
|
||||
/*override*/ void fireEvents();
|
||||
|
||||
protected:
|
||||
/*override*/ void onComputeForceImpl();
|
||||
|
||||
public:
|
||||
Running(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
// Slave side only - stays running until some other change to respond to touch events correctly
|
||||
class RunningSlave : public Named<Running, sRunningSlave>
|
||||
{
|
||||
public:
|
||||
RunningSlave(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
class Landed : public Named<RunningBase, sLanded>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return LANDED;}
|
||||
|
||||
public:
|
||||
Landed(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
|
||||
class Climbing : public Named<RunningBase, sClimbing>
|
||||
{
|
||||
private:
|
||||
typedef Named<RunningBase, sClimbing> Super;
|
||||
/*override*/ StateType getStateType() const {return CLIMBING;}
|
||||
/*override*/ void fireEvents();
|
||||
/*override*/ int ladderCheckRate() { return 0; }
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
public:
|
||||
Climbing(Humanoid* humanoid, StateType priorState) : Named<RunningBase, sClimbing>(humanoid, priorState)
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace RBX
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/Balancing.h"
|
||||
|
||||
|
||||
namespace RBX {
|
||||
class Body;
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
class RunningBase : public Balancing
|
||||
{
|
||||
private:
|
||||
typedef Balancing Super;
|
||||
protected:
|
||||
Velocity floorVelocity;
|
||||
|
||||
// The following velocities are w.r.t the ground that the figure is walking on. The ground may be moving
|
||||
Velocity desiredVelocity; // desired velocity in world coordinates relative to the floor's velocity
|
||||
float desiredAltitude; // ignored if 0.0
|
||||
|
||||
void rotateWithGround(Body* body);
|
||||
void hoverOnFloor(Body* body);
|
||||
void move(Body* body);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Humanoid::State
|
||||
/*override*/ void onComputeForceImpl();
|
||||
/*override*/ void onSimulatorStepImpl(float stepDt);
|
||||
|
||||
/*override*/ float getYAxisRotationalVelocity() const {return desiredVelocity.rotational.y;}
|
||||
|
||||
/*override*/ bool armsShouldCollide() const {return false;}
|
||||
/*override*/ bool legsShouldCollide() const {return false;}
|
||||
|
||||
public:
|
||||
RunningBase(Humanoid* humanoid, StateType priorState);
|
||||
RunningBase(Humanoid* humanoid, StateType priorState, const float kP, const float kD);
|
||||
|
||||
/*override*/ void onCFrameChangedFromReflection();
|
||||
|
||||
static const float kTurnP() {return 7500.0f;}
|
||||
static const float kTurnPForRotatePGS() {return 450.0f;}
|
||||
static const float kTurnPForFreeFallPGS() {return 375.0f;}
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace RBX
|
||||
@@ -0,0 +1,24 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/MovingNoPhysicsBase.h"
|
||||
|
||||
namespace RBX {
|
||||
class Clump;
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sRunningNoPhysics;
|
||||
|
||||
class RunningNoPhysics
|
||||
: public Named<MovingNoPhysicsBase, sRunningNoPhysics>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return RUNNING_NO_PHYS;}
|
||||
public:
|
||||
RunningNoPhysics(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
@@ -0,0 +1,48 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/HumanoidState.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char *const sSeated;
|
||||
|
||||
class Seated : public Named<HumanoidState, sSeated>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return SEATED;}
|
||||
|
||||
/*override*/ bool armsShouldCollide() const {return false;}
|
||||
/*override*/ bool legsShouldCollide() const {return false;}
|
||||
/*override*/ void onComputeForceImpl() {}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
|
||||
public:
|
||||
Seated(Humanoid* humanoid, StateType priorState);
|
||||
~Seated();
|
||||
};
|
||||
|
||||
|
||||
extern const char* const sPlatformStanding;
|
||||
|
||||
class PlatformStanding : public Named<HumanoidState, sPlatformStanding>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return PLATFORM_STANDING;}
|
||||
|
||||
/*override*/ bool armsShouldCollide() const {return false;}
|
||||
/*override*/ bool legsShouldCollide() const {return false;}
|
||||
/*override*/ void onComputeForceImpl() {}
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
|
||||
public:
|
||||
PlatformStanding(Humanoid* humanoid, StateType priorState);
|
||||
~PlatformStanding();
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "V8DataModel/ModelInstance.h"
|
||||
|
||||
namespace RBX {
|
||||
|
||||
extern const char* const sStatusInstance;
|
||||
class StatusInstance
|
||||
: public DescribedCreatable<StatusInstance, ModelInstance, sStatusInstance, Reflection::ClassDescriptor::INTERNAL>
|
||||
{
|
||||
private:
|
||||
typedef DescribedCreatable<StatusInstance, ModelInstance, sStatusInstance, Reflection::ClassDescriptor::INTERNAL> Super;
|
||||
|
||||
public:
|
||||
StatusInstance();
|
||||
|
||||
protected:
|
||||
/*override*/ bool askSetParent(const Instance* instance) const;
|
||||
/*override*/ bool askForbidParent(const Instance* instance) const { return !askSetParent(instance); }
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,24 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/MovingNoPhysicsBase.h"
|
||||
|
||||
namespace RBX {
|
||||
class Clump;
|
||||
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sStrafingNoPhysics;
|
||||
|
||||
class StrafingNoPhysics
|
||||
: public Named<MovingNoPhysicsBase, sStrafingNoPhysics>
|
||||
{
|
||||
private:
|
||||
/*override*/ StateType getStateType() const {return STRAFING_NO_PHYS;}
|
||||
public:
|
||||
StrafingNoPhysics(Humanoid* humanoid, StateType priorState);
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
@@ -0,0 +1,43 @@
|
||||
/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Humanoid/Balancing.h"
|
||||
#include "Util/Name.h"
|
||||
|
||||
namespace RBX {
|
||||
namespace HUMAN {
|
||||
|
||||
extern const char* const sSwimming;
|
||||
|
||||
class Swimming : public Named<HumanoidState, sSwimming>
|
||||
{
|
||||
private:
|
||||
typedef Named<HumanoidState, sSwimming> Super;
|
||||
Vector3 initialLinearVelocity;
|
||||
static float velocityDecay();
|
||||
|
||||
/*override*/ StateType getStateType() const {return SWIMMING;}
|
||||
/*override*/ void fireEvents();
|
||||
/*override*/ bool enableAutoJump() const { return false; }
|
||||
|
||||
Velocity desiredVelocity;
|
||||
|
||||
protected:
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Humanoid::State
|
||||
/*override*/ void onComputeForceImpl();
|
||||
/*override*/ void onSimulatorStepImpl(float stepDt);
|
||||
|
||||
public:
|
||||
Swimming(Humanoid* humanoid, StateType priorState);
|
||||
|
||||
|
||||
|
||||
static const float kTurnSpeed() {return 6.0f;} // note Humanoid autoTurnSpeed is 8.0f;
|
||||
static const float kTurnAccelMax() {return 20000.0f * kTurnSpeed();}
|
||||
};
|
||||
|
||||
} // namespace HUMAN
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user