/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #ifndef PL_HK_CALLBACK_ACTION_H #define PL_HK_CALLBACK_ACTION_H #include "hsGeometry3.h" #include "hsMatrix44.h" #include "hsTemplates.h" #include "pnKeyedObject/plKey.h" #include "plPhysical/plSimDefs.h" #include "pnMessage/plMessage.h" #include "plPhysicalControllerCore.h" class plLOSHitMsg; class plAGApplicator; class plSceneObject; class plPhysical; class plAvatarController; class plCoordinateInterface; class plPhysicalControllerCore; // Used by the other controllers to actually move the avatar. The actual // implementation is in the physics system. /*class plPhysicalController { public: // Implemented in the physics system. If you're linking this without that for // some reason, just stub this function out. // // Pass in the key to the root sceneobject for the avatar static plPhysicalController* Create(plKey ownerSO, hsScalar height, hsScalar width); virtual ~plPhysicalController() {} // A disabled avatar doesn't move or accumulate air time if he's off the ground. virtual void Enable(bool enable) = 0; virtual bool IsEnabled() const = 0; // Set the LOS DB this avatar will be in (only one) virtual void SetLOSDB(plSimDefs::plLOSDB losDB) = 0; // Call this once per frame with the velocities of the avatar in avatar space. virtual void SetVelocities(const hsVector3& linearVel, hsScalar angVel) = 0; // Gets the actual velocity we achieved in the last step (relative to our subworld) virtual const hsVector3& GetLinearVelocity() const = 0; virtual void ResetAchievedLinearVelocity() = 0; // Get and set the current subworld for the avatar. Use nil for the main world. virtual plKey GetSubworld() const = 0; virtual void SetSubworld(plKey world) = 0; // If IsOnGround returns false, GetAirTime will tell you how long the avatar // has been airborne. Use ResetAirTime to reset the air time to zero, for // cases like when the avatar spawns into a new age. virtual bool IsOnGround() const = 0; virtual bool IsOnFalseGround() const = 0; virtual hsScalar GetAirTime() const = 0; virtual void ResetAirTime() = 0; virtual plPhysical* GetPushingPhysical() const = 0; virtual bool GetFacingPushingPhysical() const = 0; // A helper function to get the coordinate interface for the avatars current // world. Handy if you need to convert points to and from that. This will // return nil if the avatar is in the main world (ie, you don't need to do // any translation). virtual const plCoordinateInterface* GetSubworldCI() const = 0; // For the avatar SDL only virtual void GetState(hsPoint3& pos, float& zRot) = 0; virtual void SetState(const hsPoint3& pos, float zRot) = 0; // kinematic stuff .... should be just for when playing a behavior... virtual void Kinematic(bool state) = 0; virtual bool IsKinematic() = 0; virtual void GetKinematicPosition(hsPoint3& pos) = 0; virtual const hsMatrix44& GetPrevSubworldW2L() = 0; //when seeking no longer want to interact with exclusion regions virtual void SetSeek(bool seek)=0; }; */ class plAvatarController { public: virtual ~plAvatarController() {} }; class plAnimatedController : public plAvatarController { public: plAnimatedController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller); virtual void RecalcVelocity(double timeNow, double timePrev, hsBool useAnim = true); void SetTurnStrength(hsScalar val) { fTurnStr = val; } hsScalar GetTurnStrength() { return fTurnStr; } virtual void ActivateController()=0; protected: plSceneObject* fRootObject; plPhysicalControllerCore* fController; plAGApplicator* fRootApp; hsScalar fAnimAngVel; hsVector3 fAnimPosVel; hsScalar fTurnStr; // Explicit turning, separate from animations }; class plWalkingController : public plAnimatedController { public: plWalkingController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller); virtual ~plWalkingController(); virtual void RecalcVelocity(double timeNow, double timePrev, hsBool useAnim = true); void Reset(bool newAge); bool IsControlledFlight() const { return fControlledFlight != 0; } bool IsOnGround() const { return fWalkingStrategy ? fWalkingStrategy->IsOnGround() : true; } bool IsOnFalseGround() const { return fWalkingStrategy ? fWalkingStrategy->IsOnFalseGround() : true; } bool HitGroundInThisAge() const { return fHitGroundInThisAge; } bool EnableControlledFlight(bool status); hsScalar GetAirTime() const { return fWalkingStrategy ? fWalkingStrategy->GetAirTime() : 0.f; } void ResetAirTime() { if (fWalkingStrategy) fWalkingStrategy->ResetAirTime(); } hsScalar GetForwardVelocity() const; void ActivateController(); // Check these after the avatar the avatar hits the ground for his total // hangtime and impact velocity. hsScalar GetImpactTime() const { return fImpactTime; } const hsVector3& GetImpactVelocity() const { return fImpactVelocity; } plPhysical* GetPushingPhysical() const { if(fController)return fController->GetPushingPhysical(); else return nil; } bool GetFacingPushingPhysical() const { if(fController)return fController->GetFacingPushingPhysical(); else return false; } protected: bool fHitGroundInThisAge; bool fWaitingForGround; // We've gone airborne. IsOnGround() returns false until we hit ground again. hsScalar fControlledFlightTime; int fControlledFlight; // Count of how many are currently forcing flight plWalkingStrategy* fWalkingStrategy; hsScalar fImpactTime; hsVector3 fImpactVelocity; bool fClearImpact; bool fGroundLastFrame;//used for a test to pass the event of first getting air during a jump static const hsScalar kControlledFlightThreshold; }; class plSwimmingController: public plAnimatedController { public : plSwimmingController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller); virtual ~plSwimmingController(); void SetSurface(plSwimRegionInterface *region, hsScalar surfaceHeight){ fSwimmingStrategy->SetSurface(region,surfaceHeight); } hsScalar GetBuoyancy() { return fSwimmingStrategy->GetBuoyancy(); } hsBool IsOnGround() { return fSwimmingStrategy->IsOnGround(); } hsBool HadContacts() { return fSwimmingStrategy->HadContacts();} void Enable(bool en){if (fController) fController->Enable(en);} plPhysicalControllerCore* GetController(){return fController;} virtual void ActivateController(){fSwimmingStrategy->RefreshConnectionToControllerCore();} protected: plSwimStrategy* fSwimmingStrategy; }; class plRidingAnimatedPhysicalController: public plWalkingController { public: plRidingAnimatedPhysicalController(plSceneObject* rootObject, plAGApplicator* rootApp, plPhysicalControllerCore* controller); virtual ~plRidingAnimatedPhysicalController(); }; #endif // PL_HK_CALLBACK_ACTION_H