// Door.cpp
// Description
// Source code that contains the implementation of a door object
// Revisions
//
#include "de_server.h"
#include "sample_servershell.h"
#include "door.h"
#include <stdio.h>
float Abs(float val)
{
if (val < 0.0f)
return (val * -1.0f);
else
return (val);
}
cDoor::cDoor() : BaseClass(OT_WORLDMODEL)
{
}
cDoor::~cDoor()
{
}
DDWORD cDoor::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT lData)
{
ObjectCreateStruct *pObjectCreateStruct;
DVector temp1,ObjPos;
DDWORD dwRet = BaseClass::EngineMessageFn(messageID, pData, lData);
// See serverobj_de.h (near line 100) for descriptions of the messages.
switch(messageID)
{
case MID_PRECREATE:
{
// As a general rule, it's best to use GetPropGeneric instead of
// GetProp<type>, tempting as the shortcut may be. Generic props
// are more flexible.
GenericProp gProp;
pObjectCreateStruct = (ObjectCreateStruct*)pData;
// Read in the Door's Starting Current State
if (GetServerDE()->GetPropGeneric("CurrentState",&gProp) == DE_OK)
{
m_eAction = (eDOORACTION)gProp.m_Long;
}
else
{
m_eAction = CLOSED;
}
// Get the Starting Position from the object
if (GetServerDE()->GetPropGeneric("StartPosition",&gProp) == DE_OK)
{
VEC_COPY(m_StartPosition, gProp.m_Vec);
}
else
{
VEC_SET(m_StartPosition,0,0,0);
}
// Get the Ending Position from the object
if (GetServerDE()->GetPropGeneric("EndPosition",&gProp) == DE_OK)
{
VEC_COPY(m_EndPosition, gProp.m_Vec);
}
else
{
VEC_SET(m_StartPosition,0,0,0);
}
GetServerDE()->CPrint("Creating the door object");
strcpy(pObjectCreateStruct->m_Filename, pObjectCreateStruct->m_Name);
pObjectCreateStruct->m_SkinName[0] = '\0';
pObjectCreateStruct->m_Flags |= FLAG_TOUCH_NOTIFY | FLAG_GOTHRUWORLD | FLAG_BOXPHYSICS;
break;
}
case MID_INITIALUPDATE:
{
DVector dims, temp1;
// set the door's initial state
m_eAction = CLOSED;
GetServerDE()->SetNextUpdate(m_hObject, 0.1f);
// get the actual Ending position
GetServerDE()->GetObjectPos(m_hObject,&ObjPos);
VEC_SUB(temp1,m_StartPosition,ObjPos);
VEC_SUB(m_StartPosition,m_StartPosition,temp1);
VEC_SUB(m_EndPosition,m_EndPosition,temp1);
VEC_INIT(dims);
VEC_INIT(temp1);
// Set the amount of Force applied to this object to be low.
GetServerDE()->SetForceIgnoreLimit(m_hObject,1);
GetServerDE()->CPrint("Initial Update of the door object");
break;
}
case MID_UPDATE:
{
// This is where we process what the door is doing.
// Then register for another update..
switch (m_eAction)
{
case STILL:
break;
case CLOSED:
break;
case BEGINOPENING:
// get the direction the Door needs to move
VEC_SUB(m_Delta,m_StartPosition,m_EndPosition);
// Make the delta ten divisons big
VEC_DIVSCALAR(m_Delta,m_Delta,10);
m_eAction = OPENING;
break;
case OPENING:
// Set the Rotation for the object.
GetServerDE()->GetObjectPos(m_hObject, &ObjPos);
if ((0.1f > Abs(ObjPos.x - m_EndPosition.x)) &&
(0.1f > Abs(ObjPos.y - m_EndPosition.y)) &&
(0.1f > Abs(ObjPos.z - m_EndPosition.z)))
{
m_eAction=OPEN;
}
else
{
VEC_SUB(ObjPos,ObjPos,m_Delta);
GetServerDE()->MoveObject(m_hObject,&ObjPos);
}
break;
case OPEN:
break;
case BEGINCLOSING:
// get the direction the Door needs to move
VEC_SUB(m_Delta,m_EndPosition,m_StartPosition);
// Make the delta ten divisons big
VEC_DIVSCALAR(m_Delta,m_Delta,10);
m_eAction = CLOSING;
break;
case CLOSING:
// Set the Position for the object.
GetServerDE()->GetObjectPos(m_hObject, &ObjPos);
if ((0.1f > Abs(ObjPos.x - m_StartPosition.x)) &&
(0.1f > Abs(ObjPos.y - m_StartPosition.y)) &&
(0.1f > Abs(ObjPos.z - m_StartPosition.z)))
{
m_eAction=CLOSED;
}
else
{
VEC_SUB(ObjPos,ObjPos,m_Delta);
GetServerDE()->MoveObject(m_hObject,&ObjPos);
}
break;
case LOCKED:
break;
case UNLOCKED:
break;
}
GetServerDE()->SetNextUpdate(m_hObject, 0.1f);
break;
}
// This is called when another object touches this object.
// pData is an HOBJECT for the other object.
// fData is the collision (stopping) force (based on masses and velocities).
case MID_TOUCHNOTIFY:
{
//Let's set the door ready to open or close
if (m_eAction == OPEN)
m_eAction=BEGINCLOSING;
if (m_eAction == CLOSED)
m_eAction = BEGINOPENING;
GetServerDE()->SetNextUpdate(m_hObject, 0.001f);
GetServerDE()->CPrint("The door object was touched");
break;
}
}
// Pass the message on down.
return dwRet;
}
// Expose the Door class for DEdit.
BEGIN_CLASS(cDoor)
ADD_VISIBLE_FLAG(1, 0)
ADD_SOLID_FLAG(1, 0)
ADD_VECTORPROP(StartPosition)
ADD_VECTORPROP(EndPosition)
ADD_LONGINTPROP(Flags, FLAG_SOLID)
ADD_LONGINTPROP(CurrentState,0)
ADD_LONGINTPROP(Key,0)
END_CLASS_DEFAULT_FLAGS(cDoor, BaseClass, NULL, NULL, 0)