PageRenderTime 24ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/GameSwingDoor.cpp

http://github.com/FrictionalGames/PenumbraOverture
C++ | 474 lines | 276 code | 112 blank | 86 comment | 40 complexity | 8043f4de29aa010829564b0ca600825c MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * Copyright (C) 2006-2010 - Frictional Games
  3. *
  4. * This file is part of Penumbra Overture.
  5. *
  6. * Penumbra Overture is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Penumbra Overture is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Penumbra Overture. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "StdAfx.h"
  20. #include "GameSwingDoor.h"
  21. #include "Init.h"
  22. #include "MapHandler.h"
  23. #include "Player.h"
  24. #include "EffectHandler.h"
  25. //-----------------------------------------------------------------------
  26. //////////////////////////////////////////////////////////////////////////
  27. // LOADER
  28. //////////////////////////////////////////////////////////////////////////
  29. //-----------------------------------------------------------------------
  30. cEntityLoader_GameSwingDoor::cEntityLoader_GameSwingDoor(const tString &asName, cInit *apInit)
  31. : cEntityLoader_Object(asName)
  32. {
  33. mpInit = apInit;
  34. }
  35. cEntityLoader_GameSwingDoor::~cEntityLoader_GameSwingDoor()
  36. {
  37. }
  38. //-----------------------------------------------------------------------
  39. void cEntityLoader_GameSwingDoor::BeforeLoad(TiXmlElement *apRootElem, const cMatrixf &a_mtxTransform,
  40. cWorld3D *apWorld)
  41. {
  42. }
  43. //-----------------------------------------------------------------------
  44. void cEntityLoader_GameSwingDoor::AfterLoad(TiXmlElement *apRootElem, const cMatrixf &a_mtxTransform,
  45. cWorld3D *apWorld)
  46. {
  47. cGameSwingDoor *pObject = hplNew( cGameSwingDoor, (mpInit,mpEntity->GetName()) );
  48. pObject->msFileName = msFileName;
  49. pObject->m_mtxOnLoadTransform = a_mtxTransform;
  50. // Set the engine objects to the object
  51. pObject->SetBodies(mvBodies);
  52. pObject->SetJoints(mvJoints);
  53. pObject->SetMeshEntity(mpEntity);
  54. pObject->SetHapticShapes(mvHapticShapes);
  55. ///////////////////////////////////
  56. // Load game properties
  57. TiXmlElement *pGameElem = apRootElem->FirstChildElement("GAME");
  58. if(pGameElem)
  59. {
  60. pObject->mfHealth = cString::ToFloat(pGameElem->Attribute("Health"),0);
  61. pObject->mlToughness = cString::ToInt(pGameElem->Attribute("Toughness"),0);
  62. pObject->msBreakSound = cString::ToString(pGameElem->Attribute("BreakSound"),"");
  63. pObject->msBreakEntity = cString::ToString(pGameElem->Attribute("BreakEntity"),"");
  64. pObject->msBreakPS = cString::ToString(pGameElem->Attribute("BreakPS"),"");
  65. }
  66. else
  67. {
  68. Error("Couldn't find game element for entity '%s'\n",mpEntity->GetName().c_str());
  69. }
  70. ///////////////////////////////////
  71. // Add a the object as user data to the body, to get the obejct later on.
  72. for(size_t i=0; i<mvBodies.size(); ++i)
  73. {
  74. if(mvBodies[i])
  75. {
  76. mvBodies[i]->SetUserData((void*)pObject);
  77. }
  78. }
  79. pObject->SetupPhysics(apWorld);
  80. pObject->SetupBreakObject();
  81. /////////////////////////////////
  82. // Add to map handler
  83. mpInit->mpMapHandler->AddGameEntity(pObject);
  84. }
  85. //-----------------------------------------------------------------------
  86. //////////////////////////////////////////////////////////////////////////
  87. // CONSTRUCTORS
  88. //////////////////////////////////////////////////////////////////////////
  89. //-----------------------------------------------------------------------
  90. cGameSwingDoor::cGameSwingDoor(cInit *apInit,const tString& asName) : iGameEntity(apInit,asName)
  91. {
  92. mType = eGameEntityType_SwingDoor;
  93. mbHasInteraction = true;
  94. mbPauseControllers = true;
  95. mbPauseGravity = true;
  96. mbLocked = false;
  97. mfHealth = 100.0f;
  98. }
  99. //-----------------------------------------------------------------------
  100. cGameSwingDoor::~cGameSwingDoor(void)
  101. {
  102. iPhysicsWorld *pPhysicsWorld = mpInit->mpGame->GetScene()->GetWorld3D()->GetPhysicsWorld();
  103. //for(size_t i=0; i<mvStopControllers.size(); ++i)
  104. //{
  105. // pPhysicsWorld->DestroyController(mvStopControllers[i]);
  106. //}
  107. }
  108. //-----------------------------------------------------------------------
  109. //////////////////////////////////////////////////////////////////////////
  110. // PUBLIC METHODS
  111. //////////////////////////////////////////////////////////////////////////
  112. //-----------------------------------------------------------------------
  113. void cGameSwingDoor::SetupPhysics(cWorld3D *apWorld)
  114. {
  115. mvJointDefaults.resize(mvJoints.size());
  116. iPhysicsWorld *pPhysicsWorld = apWorld->GetPhysicsWorld();
  117. for(size_t i=0; i<mvJoints.size(); ++i)
  118. {
  119. iPhysicsJoint *pJoint = mvJoints[i];
  120. ///////////////////////////////////
  121. //Create Stop controller
  122. iPhysicsController *pController = pPhysicsWorld->CreateController("Stop");
  123. //pController->SetBody(pJoint->GetChildBody());
  124. //pController->SetJoint(pJoint);
  125. pController->SetActive(true);
  126. pController->SetType(ePhysicsControllerType_Pid);
  127. pController->SetA(1.5f);
  128. pController->SetB(1.0f);
  129. pController->SetC(0.0f);
  130. pController->SetPidIntegralSize(20);
  131. pController->SetInputType(ePhysicsControllerInput_AngularSpeed,ePhysicsControllerAxis_Y);
  132. pController->SetDestValue(.0f);
  133. pController->SetOutputType(ePhysicsControllerOutput_Torque,ePhysicsControllerAxis_Y);
  134. pController->SetMaxOutput(0.0f);
  135. pController->SetMulMassWithOutput(true);
  136. pJoint->AddController(pController);
  137. mvStopControllers.push_back(pController);
  138. ///////////////////////////////////
  139. //Set defaults
  140. iPhysicsJointHinge *pHingeJoint = static_cast<iPhysicsJointHinge*>(pJoint);
  141. mvJointDefaults[i].mfMin = pHingeJoint->GetMinAngle();
  142. mvJointDefaults[i].mfMax = pHingeJoint->GetMaxAngle();
  143. }
  144. }
  145. //-----------------------------------------------------------------------
  146. void cGameSwingDoor::OnPlayerPick()
  147. {
  148. }
  149. //-----------------------------------------------------------------------
  150. void cGameSwingDoor::OnPlayerInteract()
  151. {
  152. float fDist = mpInit->mpPlayer->GetPickedDist();
  153. if(fDist > mfMaxInteractDist) return;
  154. if(mpInit->mbHasHaptics && mpInit->mpPlayer->mbProxyTouching==false) return;
  155. //Set some properties
  156. mpInit->mpPlayer->mfForwardUpMul = 1.0f;
  157. mpInit->mpPlayer->mfForwardRightMul = 1.0f;
  158. mpInit->mpPlayer->mfUpMul = 1.0f;
  159. mpInit->mpPlayer->mfRightMul = 1.0f;
  160. mpInit->mpPlayer->mfCurrentMaxInteractDist = mfMaxInteractDist;
  161. if(!mpInit->mbHasHaptics)
  162. {
  163. mpInit->mpPlayer->SetPushBody(mpInit->mpPlayer->GetPickedBody());
  164. mpInit->mpPlayer->ChangeState(ePlayerState_Move);
  165. }
  166. else
  167. {
  168. mpInit->mpPlayer->mbPickAtPoint = true;
  169. mpInit->mpPlayer->mbRotateWithPlayer = false;
  170. mpInit->mpPlayer->mbUseNormalMass = false;
  171. mpInit->mpPlayer->mfGrabMassMul = 1;
  172. mpInit->mpPlayer->mfHapticTorqueMul = 1.0f;
  173. mpInit->mpPlayer->mbCanBeThrown = true;
  174. mpInit->mpPlayer->mbGrabbingMoveBody = true;
  175. mpInit->mpPlayer->SetPushBody(mpInit->mpPlayer->GetPickedBody());
  176. mpInit->mpPlayer->ChangeState(ePlayerState_Grab);
  177. }
  178. }
  179. //-----------------------------------------------------------------------
  180. void cGameSwingDoor::Update(float afTimeStep)
  181. {
  182. }
  183. //-----------------------------------------------------------------------
  184. void cGameSwingDoor::SetLocked(bool abX)
  185. {
  186. if(mbLocked == abX) return;
  187. mbLocked = abX;
  188. for(size_t i=0; i<mvJoints.size(); ++i)
  189. {
  190. iPhysicsJoint *pJoint = mvJoints[i];
  191. iPhysicsJointHinge *pHingeJoint = static_cast<iPhysicsJointHinge*>(pJoint);
  192. if(mbLocked)
  193. {
  194. if(std::abs(pHingeJoint->GetMinAngle()) > std::abs(pHingeJoint->GetMaxAngle()))
  195. pHingeJoint->SetMinAngle(cMath::ToRad(-1));
  196. else
  197. pHingeJoint->SetMaxAngle(cMath::ToRad(1));
  198. }
  199. else
  200. {
  201. pHingeJoint->SetMinAngle(mvJointDefaults[i].mfMin);
  202. pHingeJoint->SetMaxAngle(mvJointDefaults[i].mfMax);
  203. }
  204. }
  205. for(size_t i=0; i<mvBodies.size(); ++i)
  206. {
  207. iPhysicsBody *pBody = mvBodies[i];
  208. pBody->SetEnabled(true);
  209. }
  210. }
  211. //-----------------------------------------------------------------------
  212. void cGameSwingDoor::OnDamage(float afDamage)
  213. {
  214. }
  215. //-----------------------------------------------------------------------
  216. void cGameSwingDoor::OnDeath(float afDamage)
  217. {
  218. if(msBreakSound != "")
  219. {
  220. cSoundEntity *pSound = mpInit->mpGame->GetScene()->GetWorld3D()->CreateSoundEntity("Break",msBreakSound,true);
  221. if(pSound)
  222. pSound->SetPosition(mvBodies[0]->GetWorldPosition());
  223. }
  224. if(msBreakEntity == "")
  225. {
  226. ///////////////////////////
  227. //Break all joints.
  228. for(size_t i=0; i< mvJoints.size();++i)
  229. {
  230. mvJoints[i]->Break();
  231. }
  232. mvJoints.clear();
  233. }
  234. else
  235. {
  236. Break();
  237. }
  238. }
  239. //-----------------------------------------------------------------------
  240. void cGameSwingDoor::BreakAction()
  241. {
  242. if(mvBodies.empty()) return;
  243. iPhysicsBody *pDynBody = NULL;
  244. iPhysicsBody *pStaticBody = NULL;
  245. for(size_t i=0; i < mvBodies.size();++i)
  246. {
  247. if(mvBodies[i]->GetMass()!=0) pDynBody = mvBodies[i];
  248. if(mvBodies[i]->GetMass()==0) pStaticBody = mvBodies[i];
  249. }
  250. if(pDynBody==NULL && pStaticBody==NULL) return;
  251. //////////////////
  252. //Script
  253. if(mvCallbackScripts[eGameEntityScriptType_OnBreak])
  254. {
  255. tString sCommand = GetScriptCommand(eGameEntityScriptType_OnBreak);
  256. mpInit->RunScriptCommand(sCommand);
  257. }
  258. cWorld3D *pWorld = mpInit->mpGame->GetScene()->GetWorld3D();
  259. //////////////////
  260. //Check if player os holding object
  261. if( (mpInit->mpPlayer->GetState()==ePlayerState_Grab ||
  262. mpInit->mpPlayer->GetState()==ePlayerState_Move ||
  263. mpInit->mpPlayer->GetState()==ePlayerState_Push)
  264. &&
  265. (mpInit->mpPlayer->GetPushBody() == pDynBody ||
  266. mpInit->mpPlayer->GetPushBody() == pStaticBody))
  267. {
  268. mpInit->mpPlayer->ChangeState(ePlayerState_Normal);
  269. }
  270. cBoundingVolume *pBV = mpMeshEntity->GetBoundingVolume();
  271. //////////////////
  272. //Particle System
  273. if(msBreakPS!="")
  274. {
  275. cParticleSystem3D *pPS = pWorld->CreateParticleSystem("Break",msBreakPS,cVector3f(1,1,1),
  276. pDynBody->GetWorldMatrix());
  277. }
  278. //////////////////
  279. //Entity
  280. if(msBreakEntity != "")
  281. {
  282. iEntity3D * pEntity = pWorld->CreateEntity(mpMeshEntity->GetName() + "_broken",
  283. pDynBody->GetWorldMatrix(),
  284. msBreakEntity, true);
  285. if(pEntity)
  286. {
  287. iGameEntity *pGameEntity = mpInit->mpMapHandler->GetLatestEntity();
  288. cVector3f vImpulse = mvLastImpulse * 2;// / (float)pGameEntity->GetBodyNum();
  289. for(int i=0; i< pGameEntity->GetBodyNum(); ++i)
  290. {
  291. //Add the object velocity
  292. iPhysicsBody *pNewBody = pGameEntity->GetBody(i);
  293. if(pNewBody->GetMass()==0 && pStaticBody)
  294. {
  295. pNewBody->SetMatrix(pStaticBody->GetWorldMatrix());
  296. }
  297. //pNewBody->SetLinearVelocity(pBody->GetLinearVelocity());
  298. pNewBody->AddImpulse(vImpulse);
  299. }
  300. }
  301. }
  302. mpInit->mpGame->ResetLogicTimer();
  303. }
  304. //-----------------------------------------------------------------------
  305. void cGameSwingDoor::SetupBreakObject()
  306. {
  307. if(msBreakEntity!="") PreloadModel(msBreakEntity);
  308. if(msBreakPS!="")
  309. {
  310. cParticleSystem3D *pPS = mpInit->mpGame->GetResources()->GetParticleManager()->CreatePS3D(
  311. "",msBreakPS,1,cMatrixf::Identity);
  312. hplDelete( pPS );
  313. }
  314. if(msBreakSound!="")
  315. {
  316. mpInit->PreloadSoundEntityData(msBreakSound);
  317. }
  318. }
  319. //-----------------------------------------------------------------------
  320. //-----------------------------------------------------------------------
  321. //////////////////////////////////////////////////////////////////////////
  322. // SAVE OBJECT STUFF
  323. //////////////////////////////////////////////////////////////////////////
  324. //-----------------------------------------------------------------------
  325. kBeginSerialize(cGameSwingDoor_SaveData,iGameEntity_SaveData)
  326. kSerializeVar(mbLocked, eSerializeType_Bool)
  327. kSerializeVar(msBreakSound, eSerializeType_String)
  328. kSerializeVar(msBreakEntity, eSerializeType_String)
  329. kSerializeVar(msBreakPS, eSerializeType_String)
  330. kEndSerialize()
  331. //-----------------------------------------------------------------------
  332. iGameEntity* cGameSwingDoor_SaveData::CreateEntity()
  333. {
  334. return NULL;
  335. }
  336. //-----------------------------------------------------------------------
  337. iGameEntity_SaveData* cGameSwingDoor::CreateSaveData()
  338. {
  339. return hplNew( cGameSwingDoor_SaveData, () );
  340. }
  341. //-----------------------------------------------------------------------
  342. void cGameSwingDoor::SaveToSaveData(iGameEntity_SaveData *apSaveData)
  343. {
  344. __super::SaveToSaveData(apSaveData);
  345. cGameSwingDoor_SaveData *pData = static_cast<cGameSwingDoor_SaveData*>(apSaveData);
  346. kCopyToVar(pData,mbLocked);
  347. kCopyToVar(pData,msBreakSound);
  348. kCopyToVar(pData,msBreakEntity);
  349. kCopyToVar(pData,msBreakPS);
  350. }
  351. //-----------------------------------------------------------------------
  352. void cGameSwingDoor::LoadFromSaveData(iGameEntity_SaveData *apSaveData)
  353. {
  354. __super::LoadFromSaveData(apSaveData);
  355. cGameSwingDoor_SaveData *pData = static_cast<cGameSwingDoor_SaveData*>(apSaveData);
  356. kCopyFromVar(pData,msBreakSound);
  357. kCopyFromVar(pData,msBreakEntity);
  358. kCopyFromVar(pData,msBreakPS);
  359. SetLocked(pData->mbLocked);
  360. }
  361. //-----------------------------------------------------------------------
  362. //-----------------------------------------------------------------------