/GameSwingDoor.cpp
http://github.com/FrictionalGames/PenumbraOverture · C++ · 474 lines · 276 code · 112 blank · 86 comment · 40 complexity · 8043f4de29aa010829564b0ca600825c MD5 · raw file
- /*
- * Copyright (C) 2006-2010 - Frictional Games
- *
- * This file is part of Penumbra Overture.
- *
- * Penumbra Overture 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.
- *
- * Penumbra Overture 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 Penumbra Overture. If not, see <http://www.gnu.org/licenses/>.
- */
- #include "StdAfx.h"
- #include "GameSwingDoor.h"
- #include "Init.h"
- #include "MapHandler.h"
- #include "Player.h"
- #include "EffectHandler.h"
- //-----------------------------------------------------------------------
- //////////////////////////////////////////////////////////////////////////
- // LOADER
- //////////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------
- cEntityLoader_GameSwingDoor::cEntityLoader_GameSwingDoor(const tString &asName, cInit *apInit)
- : cEntityLoader_Object(asName)
- {
- mpInit = apInit;
- }
- cEntityLoader_GameSwingDoor::~cEntityLoader_GameSwingDoor()
- {
- }
- //-----------------------------------------------------------------------
- void cEntityLoader_GameSwingDoor::BeforeLoad(TiXmlElement *apRootElem, const cMatrixf &a_mtxTransform,
- cWorld3D *apWorld)
- {
- }
- //-----------------------------------------------------------------------
- void cEntityLoader_GameSwingDoor::AfterLoad(TiXmlElement *apRootElem, const cMatrixf &a_mtxTransform,
- cWorld3D *apWorld)
- {
- cGameSwingDoor *pObject = hplNew( cGameSwingDoor, (mpInit,mpEntity->GetName()) );
- pObject->msFileName = msFileName;
- pObject->m_mtxOnLoadTransform = a_mtxTransform;
- // Set the engine objects to the object
- pObject->SetBodies(mvBodies);
- pObject->SetJoints(mvJoints);
- pObject->SetMeshEntity(mpEntity);
- pObject->SetHapticShapes(mvHapticShapes);
- ///////////////////////////////////
- // Load game properties
- TiXmlElement *pGameElem = apRootElem->FirstChildElement("GAME");
- if(pGameElem)
- {
- pObject->mfHealth = cString::ToFloat(pGameElem->Attribute("Health"),0);
- pObject->mlToughness = cString::ToInt(pGameElem->Attribute("Toughness"),0);
- pObject->msBreakSound = cString::ToString(pGameElem->Attribute("BreakSound"),"");
- pObject->msBreakEntity = cString::ToString(pGameElem->Attribute("BreakEntity"),"");
- pObject->msBreakPS = cString::ToString(pGameElem->Attribute("BreakPS"),"");
- }
- else
- {
- Error("Couldn't find game element for entity '%s'\n",mpEntity->GetName().c_str());
- }
- ///////////////////////////////////
- // Add a the object as user data to the body, to get the obejct later on.
- for(size_t i=0; i<mvBodies.size(); ++i)
- {
- if(mvBodies[i])
- {
- mvBodies[i]->SetUserData((void*)pObject);
- }
- }
- pObject->SetupPhysics(apWorld);
- pObject->SetupBreakObject();
- /////////////////////////////////
- // Add to map handler
- mpInit->mpMapHandler->AddGameEntity(pObject);
- }
- //-----------------------------------------------------------------------
- //////////////////////////////////////////////////////////////////////////
- // CONSTRUCTORS
- //////////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------
- cGameSwingDoor::cGameSwingDoor(cInit *apInit,const tString& asName) : iGameEntity(apInit,asName)
- {
- mType = eGameEntityType_SwingDoor;
- mbHasInteraction = true;
- mbPauseControllers = true;
- mbPauseGravity = true;
- mbLocked = false;
- mfHealth = 100.0f;
- }
- //-----------------------------------------------------------------------
- cGameSwingDoor::~cGameSwingDoor(void)
- {
- iPhysicsWorld *pPhysicsWorld = mpInit->mpGame->GetScene()->GetWorld3D()->GetPhysicsWorld();
- //for(size_t i=0; i<mvStopControllers.size(); ++i)
- //{
- // pPhysicsWorld->DestroyController(mvStopControllers[i]);
- //}
- }
- //-----------------------------------------------------------------------
- //////////////////////////////////////////////////////////////////////////
- // PUBLIC METHODS
- //////////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------
- void cGameSwingDoor::SetupPhysics(cWorld3D *apWorld)
- {
- mvJointDefaults.resize(mvJoints.size());
- iPhysicsWorld *pPhysicsWorld = apWorld->GetPhysicsWorld();
- for(size_t i=0; i<mvJoints.size(); ++i)
- {
- iPhysicsJoint *pJoint = mvJoints[i];
-
- ///////////////////////////////////
- //Create Stop controller
- iPhysicsController *pController = pPhysicsWorld->CreateController("Stop");
-
- //pController->SetBody(pJoint->GetChildBody());
- //pController->SetJoint(pJoint);
-
- pController->SetActive(true);
- pController->SetType(ePhysicsControllerType_Pid);
- pController->SetA(1.5f);
- pController->SetB(1.0f);
- pController->SetC(0.0f);
- pController->SetPidIntegralSize(20);
- pController->SetInputType(ePhysicsControllerInput_AngularSpeed,ePhysicsControllerAxis_Y);
- pController->SetDestValue(.0f);
- pController->SetOutputType(ePhysicsControllerOutput_Torque,ePhysicsControllerAxis_Y);
- pController->SetMaxOutput(0.0f);
- pController->SetMulMassWithOutput(true);
- pJoint->AddController(pController);
- mvStopControllers.push_back(pController);
- ///////////////////////////////////
- //Set defaults
- iPhysicsJointHinge *pHingeJoint = static_cast<iPhysicsJointHinge*>(pJoint);
- mvJointDefaults[i].mfMin = pHingeJoint->GetMinAngle();
- mvJointDefaults[i].mfMax = pHingeJoint->GetMaxAngle();
- }
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::OnPlayerPick()
- {
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::OnPlayerInteract()
- {
- float fDist = mpInit->mpPlayer->GetPickedDist();
- if(fDist > mfMaxInteractDist) return;
- if(mpInit->mbHasHaptics && mpInit->mpPlayer->mbProxyTouching==false) return;
- //Set some properties
- mpInit->mpPlayer->mfForwardUpMul = 1.0f;
- mpInit->mpPlayer->mfForwardRightMul = 1.0f;
- mpInit->mpPlayer->mfUpMul = 1.0f;
- mpInit->mpPlayer->mfRightMul = 1.0f;
- mpInit->mpPlayer->mfCurrentMaxInteractDist = mfMaxInteractDist;
- if(!mpInit->mbHasHaptics)
- {
- mpInit->mpPlayer->SetPushBody(mpInit->mpPlayer->GetPickedBody());
- mpInit->mpPlayer->ChangeState(ePlayerState_Move);
- }
- else
- {
- mpInit->mpPlayer->mbPickAtPoint = true;
- mpInit->mpPlayer->mbRotateWithPlayer = false;
- mpInit->mpPlayer->mbUseNormalMass = false;
- mpInit->mpPlayer->mfGrabMassMul = 1;
- mpInit->mpPlayer->mfHapticTorqueMul = 1.0f;
- mpInit->mpPlayer->mbCanBeThrown = true;
- mpInit->mpPlayer->mbGrabbingMoveBody = true;
- mpInit->mpPlayer->SetPushBody(mpInit->mpPlayer->GetPickedBody());
- mpInit->mpPlayer->ChangeState(ePlayerState_Grab);
- }
-
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::Update(float afTimeStep)
- {
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::SetLocked(bool abX)
- {
- if(mbLocked == abX) return;
- mbLocked = abX;
- for(size_t i=0; i<mvJoints.size(); ++i)
- {
- iPhysicsJoint *pJoint = mvJoints[i];
- iPhysicsJointHinge *pHingeJoint = static_cast<iPhysicsJointHinge*>(pJoint);
-
- if(mbLocked)
- {
- if(std::abs(pHingeJoint->GetMinAngle()) > std::abs(pHingeJoint->GetMaxAngle()))
- pHingeJoint->SetMinAngle(cMath::ToRad(-1));
- else
- pHingeJoint->SetMaxAngle(cMath::ToRad(1));
- }
- else
- {
- pHingeJoint->SetMinAngle(mvJointDefaults[i].mfMin);
- pHingeJoint->SetMaxAngle(mvJointDefaults[i].mfMax);
- }
- }
- for(size_t i=0; i<mvBodies.size(); ++i)
- {
- iPhysicsBody *pBody = mvBodies[i];
- pBody->SetEnabled(true);
- }
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::OnDamage(float afDamage)
- {
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::OnDeath(float afDamage)
- {
- if(msBreakSound != "")
- {
- cSoundEntity *pSound = mpInit->mpGame->GetScene()->GetWorld3D()->CreateSoundEntity("Break",msBreakSound,true);
- if(pSound)
- pSound->SetPosition(mvBodies[0]->GetWorldPosition());
- }
-
- if(msBreakEntity == "")
- {
- ///////////////////////////
- //Break all joints.
- for(size_t i=0; i< mvJoints.size();++i)
- {
- mvJoints[i]->Break();
- }
- mvJoints.clear();
- }
- else
- {
- Break();
- }
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::BreakAction()
- {
- if(mvBodies.empty()) return;
- iPhysicsBody *pDynBody = NULL;
- iPhysicsBody *pStaticBody = NULL;
- for(size_t i=0; i < mvBodies.size();++i)
- {
- if(mvBodies[i]->GetMass()!=0) pDynBody = mvBodies[i];
- if(mvBodies[i]->GetMass()==0) pStaticBody = mvBodies[i];
- }
- if(pDynBody==NULL && pStaticBody==NULL) return;
- //////////////////
- //Script
- if(mvCallbackScripts[eGameEntityScriptType_OnBreak])
- {
- tString sCommand = GetScriptCommand(eGameEntityScriptType_OnBreak);
- mpInit->RunScriptCommand(sCommand);
- }
- cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D();
- //////////////////
- //Check if player os holding object
- if( (mpInit->mpPlayer->GetState()==ePlayerState_Grab ||
- mpInit->mpPlayer->GetState()==ePlayerState_Move ||
- mpInit->mpPlayer->GetState()==ePlayerState_Push)
- &&
- (mpInit->mpPlayer->GetPushBody() == pDynBody ||
- mpInit->mpPlayer->GetPushBody() == pStaticBody))
- {
- mpInit->mpPlayer->ChangeState(ePlayerState_Normal);
- }
- cBoundingVolume *pBV = mpMeshEntity->GetBoundingVolume();
- //////////////////
- //Particle System
- if(msBreakPS!="")
- {
- cParticleSystem3D *pPS = pWorld->CreateParticleSystem("Break",msBreakPS,cVector3f(1,1,1),
- pDynBody->GetWorldMatrix());
- }
-
- //////////////////
- //Entity
- if(msBreakEntity != "")
- {
- iEntity3D * pEntity = pWorld->CreateEntity(mpMeshEntity->GetName() + "_broken",
- pDynBody->GetWorldMatrix(),
- msBreakEntity, true);
- if(pEntity)
- {
- iGameEntity *pGameEntity = mpInit->mpMapHandler->GetLatestEntity();
- cVector3f vImpulse = mvLastImpulse * 2;// / (float)pGameEntity->GetBodyNum();
- for(int i=0; i< pGameEntity->GetBodyNum(); ++i)
- {
- //Add the object velocity
- iPhysicsBody *pNewBody = pGameEntity->GetBody(i);
-
- if(pNewBody->GetMass()==0 && pStaticBody)
- {
- pNewBody->SetMatrix(pStaticBody->GetWorldMatrix());
- }
- //pNewBody->SetLinearVelocity(pBody->GetLinearVelocity());
- pNewBody->AddImpulse(vImpulse);
- }
- }
- }
- mpInit->mpGame->ResetLogicTimer();
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::SetupBreakObject()
- {
- if(msBreakEntity!="") PreloadModel(msBreakEntity);
- if(msBreakPS!="")
- {
- cParticleSystem3D *pPS = mpInit->mpGame->GetResources()->GetParticleManager()->CreatePS3D(
- "",msBreakPS,1,cMatrixf::Identity);
- hplDelete( pPS );
- }
- if(msBreakSound!="")
- {
- mpInit->PreloadSoundEntityData(msBreakSound);
- }
- }
- //-----------------------------------------------------------------------
- //-----------------------------------------------------------------------
- //////////////////////////////////////////////////////////////////////////
- // SAVE OBJECT STUFF
- //////////////////////////////////////////////////////////////////////////
- //-----------------------------------------------------------------------
- kBeginSerialize(cGameSwingDoor_SaveData,iGameEntity_SaveData)
- kSerializeVar(mbLocked, eSerializeType_Bool)
- kSerializeVar(msBreakSound, eSerializeType_String)
- kSerializeVar(msBreakEntity, eSerializeType_String)
- kSerializeVar(msBreakPS, eSerializeType_String)
- kEndSerialize()
- //-----------------------------------------------------------------------
- iGameEntity* cGameSwingDoor_SaveData::CreateEntity()
- {
- return NULL;
- }
- //-----------------------------------------------------------------------
- iGameEntity_SaveData* cGameSwingDoor::CreateSaveData()
- {
- return hplNew( cGameSwingDoor_SaveData, () );
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::SaveToSaveData(iGameEntity_SaveData *apSaveData)
- {
- __super::SaveToSaveData(apSaveData);
- cGameSwingDoor_SaveData *pData = static_cast<cGameSwingDoor_SaveData*>(apSaveData);
- kCopyToVar(pData,mbLocked);
- kCopyToVar(pData,msBreakSound);
- kCopyToVar(pData,msBreakEntity);
- kCopyToVar(pData,msBreakPS);
- }
- //-----------------------------------------------------------------------
- void cGameSwingDoor::LoadFromSaveData(iGameEntity_SaveData *apSaveData)
- {
- __super::LoadFromSaveData(apSaveData);
- cGameSwingDoor_SaveData *pData = static_cast<cGameSwingDoor_SaveData*>(apSaveData);
- kCopyFromVar(pData,msBreakSound);
- kCopyFromVar(pData,msBreakEntity);
- kCopyFromVar(pData,msBreakPS);
- SetLocked(pData->mbLocked);
- }
- //-----------------------------------------------------------------------
- //-----------------------------------------------------------------------