📄 flagobjects.cpp
字号:
/****************************************************************************
;
; MODULE: FLAGOBJECTS (.CPP)
;
; PURPOSE: Flag Objects for CTF
;
; HISTORY: 12/30/98 [blg] This file was created
;
; COMMENT: Copyright (c) 1998, Monolith Productions Inc.
;
****************************************************************************/
// Includes...
#include "FlagObjects.h"
#include "ObjectUtilities.h"
#include "Spawner.h"
#include "StdIo.h"
#include <mbstring.h>
#include "SoundTypes.h"
// Statics...
static FlagObject* s_pTeam1Flag = NULL;
static FlagObject* s_pTeam2Flag = NULL;
// Functions...
// *********************************************************************** //
// FlagObject
BEGIN_CLASS(FlagObject)
ADD_STRINGPROP(ObjectName, "CTF_Flag") // Item name
ADD_LONGINTPROP(TeamID, 0) // Team ID (1 or 2)
END_CLASS_DEFAULT(FlagObject, B2BaseClass, NULL, NULL)
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::~FlagObject
//
// PURPOSE: Destructor
//
// ----------------------------------------------------------------------- //
FlagObject::~FlagObject()
{
if (g_pServerDE && m_hFlagGrabString)
{
g_pServerDE->FreeString(m_hFlagGrabString);
m_hFlagGrabString = DNULL;
}
if (this == s_pTeam1Flag)
{
s_pTeam1Flag = NULL;
}
if (this == s_pTeam2Flag)
{
s_pTeam2Flag = NULL;
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::EngineMessageFn
//
// PURPOSE: Handler for engine messages
//
// ----------------------------------------------------------------------- //
DDWORD FlagObject::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
// Handle the engine messages we're interested in...
switch(messageID)
{
case MID_PRECREATE:
{
if (fData == PRECREATE_WORLDFILE || fData == PRECREATE_STRINGPROP)
{
ReadProp((ObjectCreateStruct*)pData);
}
PostPropRead((ObjectCreateStruct*)pData);
break;
}
case MID_INITIALUPDATE:
{
OnInitialUpdate(pData, fData);
break;
}
case MID_TOUCHNOTIFY:
{
if (!IsWithPlayer())
{
OnTouchNotify((HOBJECT)pData);
}
break;
}
case MID_UPDATE:
{
if (IsOnGround())
{
ReturnToFlagStand();
}
break;
}
}
return B2BaseClass::EngineMessageFn(messageID, pData, fData);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::ReadProp
//
// PURPOSE: Reads FlagObject properties
//
// ----------------------------------------------------------------------- //
DBOOL FlagObject::ReadProp(ObjectCreateStruct *pStruct)
{
GenericProp genProp;
if (g_pServerDE->GetPropGeneric("TeamID", &genProp) == DE_OK)
{
m_nTeamID = (int)genProp.m_Long;
}
return DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagStand::PostPropRead()
//
// PURPOSE: Updates the properties now that they have been read
//
// ----------------------------------------------------------------------- //
void FlagObject::PostPropRead(ObjectCreateStruct* pStruct)
{
// Sanity checks...
if (!pStruct) return;
// Set the flags we want...
pStruct->m_Flags |= FLAG_TOUCH_NOTIFY | FLAG_VISIBLE;
pStruct->m_Flags &= ~FLAG_GRAVITY;
g_pServerDE->SetNextUpdate(m_hObject, 0.001f);
// Set the model filename
if (m_nTeamID == 1)
{
char* pFilename = "Models\\WorldObjects\\flagblue.abc";
_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)pFilename);
}
else if (m_nTeamID == 2)
{
char* pFilename = "Models\\WorldObjects\\flagred.abc";
_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)pFilename);
}
// Set the skin filename
if (m_nTeamID == 1)
{
char* pSkin = "Skins\\WorldObjects\\flagblue.dtx";
_mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)pSkin);
}
else if (m_nTeamID = 2)
{
char* pSkin = "Skins\\WorldObjects\\flagred.dtx";
_mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)pSkin);
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::OnInitialUpdate()
//
// PURPOSE: Handles the MID_INITIALUPDATE engine message
//
// ----------------------------------------------------------------------- //
void FlagObject::OnInitialUpdate(void* pData, DFLOAT fData)
{
// Set the dims...
DVector vDims;
g_pServerDE->GetModelAnimUserDims(m_hObject, &vDims, g_pServerDE->GetModelAnimation(m_hObject));
if (g_pServerDE->SetObjectDims2(m_hObject, &vDims) == DE_ERROR)
{
g_pServerDE->SetObjectDims(m_hObject, &vDims);
}
// Save our initial flag stand position...
g_pServerDE->GetObjectPos(m_hObject, &m_vStand);
g_pServerDE->GetObjectRotation(m_hObject, &m_rStand);
m_bInStand = DTRUE;
m_bOnGround = DFALSE;
m_bWithPlayer = DFALSE;
// Set our static pointer...
if (m_nTeamID == TEAM_1)
{
s_pTeam1Flag = this;
}
if (m_nTeamID == TEAM_2)
{
s_pTeam2Flag = this;
}
// Create our trigger string if necessary...
if (!m_hFlagGrabString)
{
m_hFlagGrabString = g_pServerDE->CreateString("flaggrab");
}
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::ObjectMessageFn
//
// PURPOSE: Handle messages from objects
//
// ----------------------------------------------------------------------- //
DDWORD FlagObject::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
switch (messageID)
{
case MID_TRIGGER:
{
// Get the trigger name...
HSTRING hMsg = g_pServerDE->ReadFromMessageHString(hRead);
if (hMsg)
{
char* sMsg = g_pServerDE->GetStringData(hMsg);
if (sMsg)
{
// Check if we should return to the flag stand...
if (_mbsicmp((const unsigned char*)sMsg, (const unsigned char*)"return") == 0)
{
ReturnToFlagStand();
}
}
g_pServerDE->FreeString(hMsg);
}
break;
}
default: break;
}
return B2BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::SetPos
//
// PURPOSE: Sets the flags position to the given value
//
// ----------------------------------------------------------------------- //
void FlagObject::SetPos(DVector* pPos)
{
// Sanity checks...
if (!pPos) return;
if (!g_pServerDE) return;
// Set the objects position...
g_pServerDE->SetObjectPos(m_hObject, pPos);
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::ReturnToFlagStand
//
// PURPOSE: Moves the flag back to it's original flag stand position
//
// ----------------------------------------------------------------------- //
void FlagObject::ReturnToFlagStand()
{
// If we're already in our flag stand, just return...
if (m_bInStand) return;
// Set our "stand" position...
DRotation rTemp;
g_pServerDE->SetupEuler(&rTemp, 1, 1, 1);
g_pServerDE->SetObjectRotation(m_hObject, &rTemp);
g_pServerDE->SetObjectPos(m_hObject, &m_vStand);
g_pServerDE->SetObjectRotation(m_hObject, &m_rStand);
// Play a cool respawn sound...
char* sSound = "sounds_multipatch\\CtfFlagRespawn.WAV";
PlaySoundFromPos(&m_vStand, sSound, 2000.0f, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DFALSE, DFALSE);
// Flag that we are back in our stand...
m_bInStand = DTRUE;
m_bOnGround = DFALSE;
m_bWithPlayer = DFALSE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::GiveToPlayer
//
// PURPOSE: Gives the flag to a player
//
// ----------------------------------------------------------------------- //
void FlagObject::GiveToPlayer()
{
// Set all the flags such that we are being carried by a player...
m_bInStand = DFALSE;
m_bOnGround = DFALSE;
m_bWithPlayer = DTRUE;
}
// ----------------------------------------------------------------------- //
//
// ROUTINE: FlagObject::DropToGround()
//
// PURPOSE: Drops the flag to the ground
//
// ----------------------------------------------------------------------- //
void FlagObject::DropToGround()
{
// Move the flag to the ground...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -