CollisionBox.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. //============================================================================================
  2. // Spirenkov Maxim, 2005
  3. //============================================================================================
  4. // Mission objects
  5. //============================================================================================
  6. // CollisionBox
  7. //============================================================================================
  8. #include "CollisionBox.h"
  9. MissionCollisionBox::MissionCollisionBox(): colliders(_FL_)
  10. {
  11. needAiRegistry = false;
  12. aiColider = null;
  13. }
  14. MissionCollisionBox::~MissionCollisionBox()
  15. {
  16. DelAllColliders();
  17. RELEASE(aiColider);
  18. }
  19. //Инициализировать объект
  20. bool MissionCollisionBox::Create(MOPReader & reader)
  21. {
  22. DelAllColliders();
  23. needAiRegistry = false;
  24. InitParams(reader);
  25. PhysicsCollisionGroup groups[] = { phys_world, phys_character, phys_player, phys_enemy, phys_ally, phys_boss};
  26. for (int i=0;i<(int)(sizeof(groups)/sizeof(PhysicsCollisionGroup));i++)
  27. {
  28. if (reader.Bool())
  29. {
  30. AddCollider(groups[i]);
  31. if (phys_character == groups[i])
  32. {
  33. needAiRegistry = true;
  34. }
  35. }
  36. }
  37. Activate(reader.Bool());
  38. if(reader.Bool())
  39. {
  40. SetUpdate(&MissionCollisionBox::Draw, ML_DYNAMIC1);
  41. }
  42. return true;
  43. }
  44. //Пересоздать объект
  45. void MissionCollisionBox::Restart()
  46. {
  47. ReCreate();
  48. }
  49. //Обработчик команд для объекта
  50. void MissionCollisionBox::Command(const char * id, dword numParams, const char ** params)
  51. {
  52. if(!id || !id[0]) return;
  53. if(string::IsEqual(id, "teleport"))
  54. {
  55. if(numParams < 1) return;
  56. MOSafePointer obj;
  57. if(FindObject(ConstString(params[0]), obj))
  58. {
  59. Matrix mObj;
  60. obj.Ptr()->GetMatrix(mObj);
  61. if(aiColider)
  62. {
  63. aiColider->SetMatrix(mObj);
  64. }
  65. for (int i=0;i<(int)colliders.Size();i++)
  66. {
  67. colliders[i]->SetTransform(mObj);
  68. }
  69. LogicDebug("Teleport box \"%s\" to mission object \"%s\"", GetObjectID().c_str(), obj.Ptr()->GetObjectID().c_str());
  70. }
  71. else
  72. {
  73. LogicDebugError("Can't teleport box \"%s\" to mission object \"%s\", object not found...", GetObjectID().c_str(), params[0]);
  74. }
  75. }
  76. }
  77. //Инициализировать объект
  78. bool MissionCollisionBox::EditMode_Create(MOPReader & reader)
  79. {
  80. InitParams(reader);
  81. MissionObject::Activate(reader.Bool());
  82. SetUpdate(&MissionCollisionBox::Draw, ML_DYNAMIC1);
  83. return true;
  84. }
  85. //Обновить параметры
  86. bool MissionCollisionBox::EditMode_Update(MOPReader & reader)
  87. {
  88. InitParams(reader);
  89. return true;
  90. }
  91. //Получить размеры описывающего ящика
  92. void MissionCollisionBox::EditMode_GetSelectBox(Vector & min, Vector & max)
  93. {
  94. min = -aiColider->GetBoxSize()*0.5f;
  95. max = aiColider->GetBoxSize()*0.5f;
  96. }
  97. void MissionCollisionBox::GetBox(Vector & min, Vector & max)
  98. {
  99. min = -aiColider->GetBoxSize()*0.5f;
  100. max = aiColider->GetBoxSize()*0.5f;
  101. }
  102. //Получить матрицу объекта
  103. Matrix & MissionCollisionBox::GetMatrix(Matrix & mtx)
  104. {
  105. return (mtx = aiColider->GetMatrix());
  106. }
  107. //Нарисовать модельку
  108. void _cdecl MissionCollisionBox::Draw(float dltTime, long level)
  109. {
  110. if(!EditMode_IsVisible()) return;
  111. if(!Mission().EditMode_IsAdditionalDraw()) return;
  112. Render().DrawSolidBox(-aiColider->GetBoxSize()*0.5f, aiColider->GetBoxSize()*0.5f, aiColider->GetMatrix(), IsActive() ? 0xff00ff00 : 0xffff0000);
  113. }
  114. //Активировать/деактивировать объект
  115. void MissionCollisionBox::Activate(bool isActive)
  116. {
  117. MissionObject::Activate(isActive);
  118. for (int i=0;i<(int)colliders.Size();i++)
  119. {
  120. colliders[i]->Activate(isActive);
  121. }
  122. if(needAiRegistry)
  123. {
  124. aiColider->Activate(isActive);
  125. }
  126. }
  127. void MissionCollisionBox::InitParams(MOPReader & reader)
  128. {
  129. if(!aiColider)
  130. {
  131. aiColider = QTCreateObject(MG_AI_COLLISION, _FL_);
  132. }
  133. aiColider->Activate(false);
  134. aiColider->SetBoxCenter(0.0f);
  135. Vector size;
  136. size.x = reader.Float();
  137. size.y = reader.Float();
  138. size.z = reader.Float();
  139. aiColider->SetBoxSize(size);
  140. Vector pos = reader.Position();
  141. Vector ang = reader.Angles();
  142. aiColider->SetMatrix(Matrix(ang, pos));
  143. }
  144. void MissionCollisionBox::AddCollider(PhysicsCollisionGroup group)
  145. {
  146. IPhysBox* collider = Physics().CreateBox(_FL_, aiColider->GetBoxSize(), aiColider->GetMatrix(), false);
  147. collider->SetGroup(group);
  148. colliders.Add(collider);
  149. }
  150. void MissionCollisionBox::DelAllColliders()
  151. {
  152. for (int i=0;i<(int)colliders.Size();i++)
  153. {
  154. colliders[i]->Release();
  155. }
  156. colliders.DelAll();
  157. }
  158. //============================================================================================
  159. //Параметры инициализации
  160. //============================================================================================
  161. MOP_BEGINLISTCG(MissionCollisionBox, "Collision box", '1.00', 0, "Designer's defined collision box", "Physics")
  162. MOP_FLOATEX("Width", 3.0f, 0.01f, 100.0f)
  163. MOP_FLOATEX("Height", 3.0f, 0.01f, 100.0f)
  164. MOP_FLOATEX("Length", 0.5f, 0.01f, 100.0f)
  165. MOP_POSITION("Position", Vector(0.0f))
  166. MOP_ANGLES("Angles", Vector(0.0f))
  167. MOP_BOOLC("World", false, "Collision with physic objects")
  168. MOP_BOOLC("Characters", true, "Collision with any character (include player)")
  169. MOP_BOOLC("Player", false, "Collision with player")
  170. MOP_BOOLC("Enemy", false, "Collision with enemy")
  171. MOP_BOOLC("Ally", false, "Collision with ally")
  172. MOP_BOOLC("Boss", false, "Collision with boss")
  173. MOP_BOOL("Active", true)
  174. MOP_BOOL("Debug draw", false)
  175. MOP_ENDLIST(MissionCollisionBox)