| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- //===========================================================================================================================
- // Spirenkov Maxim, 2003
- //===========================================================================================================================//
- // Mission objects
- //===========================================================================================================================
- // AcceptDetector
- //============================================================================================
-
- #include "AcceptDetector.h"
- //============================================================================================
- AcceptDetector::AcceptDetector()
- {
- isTrgInside = false;
- isSelected = false;
- acceptEnable = true;
- }
- AcceptDetector::~AcceptDetector()
- {
- }
- //============================================================================================
- //Инициализировать объект
- bool AcceptDetector::Create(MOPReader & reader)
- {
- target.Reset();
- isTrgInside = false;
- isSelected = false;
- acceptEnable = true;
- connect.Reset();
- if(!AcceptorObject::Create(reader)) return false;
- //Получим идентификатор объекта
- targetID = reader.String();
- //Получить позицию
- iniPos = sphere.pos = reader.Position();
- //Получить радиус
- sphere.radius = reader.Float();
- //Активация
- Activate(reader.Bool());
- acceptEnable = reader.Bool();
- checkDirection = reader.Bool();
- //Триггеры
- eventAccept.Init(reader);
- eventEnter.Init(reader);
- eventExit.Init(reader);
- connectID = reader.String();
- UpdatePosition();
- //Сбрасывать ли состояние после срабатывания
- return UpdateTarget();
- }
- //Получить матрицу объекта
- Matrix & AcceptDetector::GetMatrix(Matrix & mtx)
- {
- return mtx.BuildPosition(sphere.pos);
- }
- //Активировать
- void AcceptDetector::Activate(bool isActive)
- {
- AcceptorObject::Activate(isActive);
- if(!EditMode_IsOn())
- {
- if(IsActive())
- {
- LogicDebug("Activate");
- SetUpdate(&AcceptDetector::Work, ML_TRIGGERS);
- }else{
- LogicDebug("Deactivate");
- DelUpdate(&AcceptDetector::Work);
- Unregistry(MG_ACTIVEACCEPTOR);
- /* if(isTrgInside)
- {
- eventExit.Activate(Mission(), false);
- isTrgInside = false;
- }*/
- isSelected = false;
- }
- }
- }
- //Воздействовать на объект
- bool AcceptDetector::Accept(MissionObject * obj)
- {
- if(!target.Validate()) return false;
- if(obj != target.Ptr()) return false;
- LogicDebug("Triggering");
- eventAccept.Activate(Mission(), false);
- return false;
- }
- //Инициализировать объект
- bool AcceptDetector::EditMode_Create(MOPReader & reader)
- {
- if(!AcceptorObject::Create(reader)) return false;
- EditMode_Update(reader);
- return true;
- }
- //Обновить параметры
- bool AcceptDetector::EditMode_Update(MOPReader & reader)
- {
- SetUpdate(&AcceptDetector::EditModeWork, ML_ALPHA5);
- Create(reader);
- DelUpdate(&AcceptDetector::Work);
- return true;
- }
- //Получить размеры описывающего ящика
- void AcceptDetector::EditMode_GetSelectBox(Vector & min, Vector & max)
- {
- min = -sphere.radius - 0.1f;
- max = sphere.radius + 0.1f;
- }
- //============================================================================================
- //Работа детектора
- void _cdecl AcceptDetector::Work(float dltTime, long level)
- {
- if(!target.Validate())
- {
- isSelected = false;
- Unregistry(MG_ACTIVEACCEPTOR);
- target.Reset();
- return;
- }
- //Обновляем позицию
- UpdatePosition();
- //Анализируем
- Matrix targetTransform;
- target.Ptr()->GetMatrix(targetTransform);
- //Проверяем пересечение сферы с отрезком
- Vector dv = sphere.pos - targetTransform.pos;
- bool isInside = (~dv <= sphere.r*sphere.r);
- if(isTrgInside != isInside)
- {
- isTrgInside = isInside;
- if(isTrgInside)
- {
- eventEnter.Activate(Mission(), false);
- }else{
- eventExit.Activate(Mission(), false);
- }
- }
- if(acceptEnable)
- {
- if(checkDirection && (targetTransform.vz | dv) < 0.0f)
- {
- isInside = false;
- }
- if(isSelected != isInside)
- {
- isSelected = isInside;
- if(isSelected)
- {
- Registry(MG_ACTIVEACCEPTOR);
- }else{
- Unregistry(MG_ACTIVEACCEPTOR);
- }
- }
- }
- }
- //Работа детектора в режиме редактирования
- void _cdecl AcceptDetector::EditModeWork(float dltTime, long level)
- {
- if(!Mission().EditMode_IsAdditionalDraw()) return;
- if(!EditMode_IsVisible()) return;
- //Обновляем состояние
- dword clr;
- UpdateTarget();
- if(target.Validate())
- {
- if(IsActive())
- {
- clr = 0xff00ffcc;
- }else{
- clr = 0xcccccc80;
- }
- }else{
- clr = 0xffff508c;
- }
- UpdatePosition();
- //Рисуем
- Render().DrawSphere(sphere.pos, sphere.radius, clr, "ShowDetector");
- if(EditMode_IsSelect())
- {
- Render().Print(sphere.pos, -1.0f, -1.0f, 0xffffffff, "Object id: %s", GetObjectID().c_str());
- Render().Print(sphere.pos, -1.0f, 0.0f, 0xffffffff, "Target: %s", targetID.c_str());
- Render().Print(sphere.pos, -1.0f, 1.0f, 0xffffffff, IsActive() ? "State: on" : "State: off");
- }
- }
- //Обновить цель
- bool AcceptDetector::UpdateTarget()
- {
- if(!FindObject(targetID, target)) return false;
- Matrix mtx(true);
- target.Ptr()->GetMatrix(mtx);
- targetPos = mtx.pos;
- return true;
- }
- //Обновить позицию
- void AcceptDetector::UpdatePosition()
- {
- if(connectID.NotEmpty())
- {
- if(!connect.Validate())
- {
- FindObject(connectID, connect);
- }
- }
- if(connect.Validate())
- {
- sphere.pos = connect.Ptr()->GetMatrix(Matrix())*iniPos;
- }else{
- sphere.pos = iniPos;
- }
- }
- //============================================================================================
- //Параметры инициализации
- //============================================================================================
- MOP_BEGINLISTCG(AcceptDetector, "Accept detector", '1.00', 0x0fffffff, "Detector accept action from some mission object", "Logic")
- MOP_STRING("Object id", "Player")
- MOP_POSITION("Position", Vector(0.0f))
- MOP_FLOATEX("Radius", 1.0f, 0.001f, 1000000.0f)
- MOP_BOOL("Active", true)
- MOP_BOOLC("Accept", true, "Enable accept perception")
- MOP_BOOLC("Direction", false, "Check direction, when accept")
- MOP_MISSIONTRIGGERG("Accept trigger", "Accept.")
- MOP_MISSIONTRIGGERG("Enter trigger", "Enter.")
- MOP_MISSIONTRIGGERG("Exit trigger", "Exit.")
- MOP_STRING("Connect to object", "")
- MOP_ENDLIST(AcceptDetector)
|