⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 seeingeye.cpp

📁 Blood 2全套源码
💻 CPP
字号:
// ----------------------------------------------------------------------- //
//
// MODULE  : SeeingEye.cpp
//
// PURPOSE : DefenseGlobe AI
//
// CREATED : 12/01/97   
//
// ----------------------------------------------------------------------- //


// 9.4.5 The all-seeing Eye!

// The all-seeing eye looks like a normal human eye (dislodged from someone's head, of course).  
// The player can drop it anywhere, or throw it by holding down on it's hot key.  Once the eye is 
// in place the player can look through it and see what it sees by pressing it's hot key a second 
// time.  The eye is easily destroyed, and if they player is looking through it when this happens 
// they are blinded for several seconds.  Once the eye is destroyed it will automatically return 
// to the player's inventory.

// Need a Eye model
// Reposition the Camera to eye models location
// Mlook only
// Change Screen border?
// 

#include "SeeingEye.h"
#include "cpp_server_de.h"
#include "SharedDefs.h"
#include "PlayerObj.h"
#include "ClientServerShared.h"

//BEGIN_CLASS(CPlayerObj)
//END_CLASS_DEFAULT(CPlayerObj, CBaseCharacter, NULL, NULL)

BEGIN_CLASS(SeeingEye)
	ADD_DESTRUCTABLE_AGGREGATE()
END_CLASS_DEFAULT_FLAGS(SeeingEye, BaseClass, NULL, NULL, CF_HIDDEN)

#define PINGPERIOD 1.0f

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	
//
//	PURPOSE:	Constructor
//
// ----------------------------------------------------------------------- //
SeeingEye::SeeingEye() : BaseClass(OT_MODEL)
{
	AddAggregate(&m_damage);
	m_hOwner = DNULL;
	m_hClient = DNULL;
    m_bDropped = DFALSE;
    m_hStuckObject = DNULL;
	m_fNextPingTime = 0;
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	
//
//	PURPOSE:	Destructor
//
// ----------------------------------------------------------------------- //
SeeingEye::~SeeingEye()
{
	Remove( DTRUE );
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	SeeingEye::Init()
//
//	PURPOSE:	Initializes the SeeingEye
//
// ----------------------------------------------------------------------- //
void SeeingEye::Init(HOBJECT hOwner, HCLIENT hClient)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();

	m_hOwner = hOwner;
	if( m_hOwner )
	{
		g_pServerDE->CreateInterObjectLink( m_hObject, m_hOwner );
	}
	m_hClient = hClient;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	EngineMessageFn
//
//	PURPOSE:	Handle engine messages
//
// ----------------------------------------------------------------------- //

DDWORD SeeingEye::EngineMessageFn(DDWORD messageID, void *pData, DFLOAT fData)
{
	switch(messageID)
	{
		case MID_PRECREATE:
		{
			DDWORD dwRet = BaseClass::EngineMessageFn(messageID, pData, fData);

			if( fData != INITIALUPDATE_SAVEGAME )
				PostPropRead((ObjectCreateStruct*)pData);

			return dwRet;
		}


		case MID_INITIALUPDATE:
		{
			if( fData != INITIALUPDATE_SAVEGAME )
				InitialUpdate((DVector *)pData);
			break;
		}

		case MID_UPDATE:
		{
			Update();
			break;
		}

		case MID_TOUCHNOTIFY:
		{
			ObjectTouch((HOBJECT)pData);
		}
		break;

		case MID_LINKBROKEN:
		{
			if( m_hStuckObject == (HOBJECT)pData )
			{
				Pickup( );
			}
			else if( m_hOwner == (HOBJECT)pData )
			{
				Remove( DTRUE );
			}

		}
		break;

		case MID_SAVEOBJECT:
			Save((HMESSAGEWRITE)pData, (DDWORD)fData);
			break;

		case MID_LOADOBJECT:
			Load((HMESSAGEREAD)pData, (DDWORD)fData);
			break;

		default : break;
	}


	return BaseClass::EngineMessageFn(messageID, pData, fData);
}

// --------------------------------------------------------------------------- //
//
//	ROUTINE:	SeeingEye::ObjectMessageFn()
//
//	PURPOSE:	Processes a message from a server object.
//
// --------------------------------------------------------------------------- //
DDWORD SeeingEye::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
	DDWORD dwRet;

	switch(messageID)
	{
		case MID_UNATTACH:
		{
			if( hSender == m_hStuckObject )
			{
				Pickup( );
			}
		}
		break;

		case MID_DAMAGE:
		{
			dwRet = BaseClass::ObjectMessageFn(hSender, messageID, hRead);

			if(m_damage.IsDead() )
			{
				Remove( DTRUE );
			}

			return dwRet;
		}
		break;
	}

	return BaseClass::ObjectMessageFn(hSender, messageID, hRead);
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	PostPropRead()
//
//	PURPOSE:	Update properties
//
// ----------------------------------------------------------------------- //

void SeeingEye::PostPropRead(ObjectCreateStruct *pStruct)
{
	if (!pStruct) return;
	char* pFilename = "Models\\Powerups\\theeye_pu.abc";
	char* pSkin = "Skins\\Powerups\\theeye_pu.dtx";

	_mbscpy((unsigned char*)pStruct->m_Filename, (const unsigned char*)pFilename);
	_mbscpy((unsigned char*)pStruct->m_SkinName, (const unsigned char*)pSkin);

	pStruct->m_Flags = FLAG_VISIBLE | FLAG_GRAVITY | FLAG_SOLID | FLAG_TOUCH_NOTIFY | FLAG_NOSLIDING | FLAG_REMOVEIFOUTSIDE;

}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	ObjectTouch
//
//	PURPOSE:	Handle object touch
//
// ----------------------------------------------------------------------- //

void SeeingEye::ObjectTouch (HOBJECT hObj)
{
	DDWORD dwFlags;
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;

	// return if it hit a non solid object, but not if it hit a world object
	HOBJECT hWorld = pServerDE->GetWorldObject();

	if (hObj != hWorld && !(pServerDE->GetObjectFlags(hObj) & FLAG_SOLID)) // Ignore non-solid objects
		return;

	if (!m_bDropped)
	{
		if (hObj == m_hOwner)
			return; // Let it get out of our bounding box...

		m_bDropped = DTRUE;
		DVector vVel;
		VEC_SET(vVel, 0, 0, 0)
		// Stop moving
		pServerDE->SetVelocity(m_hObject, &vVel);
		pServerDE->SetAcceleration(m_hObject, &vVel);

		dwFlags = pServerDE->GetObjectFlags( m_hObject );

		if (hObj != hWorld)
		{
			m_hStuckObject = hObj;

			Attach( );

			// Not solid anymore, and no gravity.
			dwFlags &= ~( FLAG_SOLID | FLAG_GRAVITY );
		}
		
		pServerDE->SetObjectFlags(m_hObject, dwFlags );
	}
	else
	{
		// Pickup the eye
		if (hObj == m_hOwner)
		{
			Pickup( );
		}
	}
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Attach()
//
//	PURPOSE:	Attaches eye to object
//
// ----------------------------------------------------------------------- //

void SeeingEye::Attach( )
{
	HMESSAGEWRITE hMsg;

	g_pServerDE->CreateInterObjectLink( m_hObject, m_hStuckObject );
	hMsg = g_pServerDE->StartMessageToObject( this, m_hStuckObject, MID_ATTACH );
	g_pServerDE->WriteToMessageObject( hMsg, m_hObject );
	g_pServerDE->EndMessage( hMsg );
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	Pickup()
//
//	PURPOSE:	Pickup the eye
//
// ----------------------------------------------------------------------- //

void SeeingEye::Pickup( )
{
	DVector vPos;

	// Make sure it's a player
	if( IsPlayer( m_hOwner ))
	{
		CPlayerObj *pOwner = (CPlayerObj*)g_pServerDE->HandleToObject(m_hOwner);

		if( pOwner )
		{
			// Deactivate the Eye (in InventoryMgr)
			CInvItem *pInvItem = pOwner->m_InventoryMgr.GetItem(INV_THEEYE);
			if( pInvItem )
			{
				pInvItem->PickItUp();

				g_pServerDE->GetObjectPos( m_hObject, &vPos );
				PlaySoundFromPos( &vPos, "sounds\\powerups\\inventory1.wav", 300.0f, SOUNDPRIORITY_MISC_HIGH);
			}
		}
	}

	Remove( DFALSE );
}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	InitialUpdate()
//
//	PURPOSE:	Handle initial update
//
// ----------------------------------------------------------------------- //

DBOOL SeeingEye::InitialUpdate(DVector *pMovement)
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return DFALSE;

	m_damage.Init(m_hObject);
    
	m_damage.SetHitPoints(10.0f);
	m_damage.SetMaxHitPoints(10.0f);
	m_damage.SetArmorPoints(0.0f);
	m_damage.SetMaxArmorPoints(0.0f);
	m_damage.SetMass(30.0f);
    
	// Set the dims...
	DVector vDims;
	VEC_SET(vDims, 7, 7, 7);
	pServerDE->SetObjectDims(m_hObject, &vDims);

    // Toss the Eye up
	DRotation rRot;
	DVector vU, vR, vF;
	pServerDE->GetObjectRotation(m_hObject, &rRot);
	pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);
	DVector vVel;
    
    DFLOAT fForward = pServerDE->Random(150.0f, 250.0f);
	VEC_MULSCALAR(vF, vF, fForward);

	DFLOAT fUpVel = pServerDE->Random(100.0f, 150.0f);
	VEC_MULSCALAR(vU, vU, fUpVel);
    
	VEC_ADD(vVel, vU, vF);
	pServerDE->SetVelocity(m_hObject, &vVel);

	pServerDE->SetForceIgnoreLimit(m_hObject, 0.0f);
	pServerDE->SetFrictionCoefficient(m_hObject, 18.0);

	pServerDE->SetNextUpdate(m_hObject, (DFLOAT)0.001);

	pServerDE->SetObjectUserFlags( m_hObject, USRFLG_SAVEABLE );

	return DTRUE;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	SeeingEye::Update
//
//	PURPOSE:
//
// ----------------------------------------------------------------------- //
void SeeingEye::Update()
{
	CServerDE* pServerDE = GetServerDE();

	pServerDE->SetNextUpdate(m_hObject, 0.001f);

	if( pServerDE->GetTime( ) > m_fNextPingTime )
	{
		m_fNextPingTime = pServerDE->GetTime( ) + PINGPERIOD;
		pServerDE->PingObjects(m_hObject);
	}

    if (m_bDropped)
	{
		DVector vVel;
		VEC_SET(vVel, 0, 0, 0);
		pServerDE->SetVelocity(m_hObject, &vVel);
	}

	if (m_hStuckObject)
	{
		// Move to keep up with what we hit
	    DVector vPos, vDims;
        pServerDE->GetObjectPos(m_hStuckObject, &vPos);
    	pServerDE->GetObjectDims(m_hStuckObject, &vDims);
        
        // Position the Eye at Eye Level...
    	vPos.y += vDims.y / 2.0f;
	    vPos.y -= 10;       // on Players Back
	    vPos.z -= 10;       // on Players Back
	
		pServerDE->TeleportObject(m_hObject, &vPos);
	}

	return;
}


// ----------------------------------------------------------------------- //
//
//	ROUTINE:	SeeingEye::Remove
//
//	PURPOSE:	Removes the object
//
// ----------------------------------------------------------------------- //

void SeeingEye::Remove( DBOOL bClearInv )
{
	// Make the Inventory Item NULL
	if (m_hOwner)
	{
		if( IsPlayer( m_hOwner ))
    	{
			CPlayerObj *pOwner = (CPlayerObj*)g_pServerDE->HandleToObject(m_hOwner);

			if( pOwner )
			{
				if ( pOwner->m_InventoryMgr.IsItemActive(INV_THEEYE))
				{
					int nOff = 0;
					if (m_hClient)
					{
						HMESSAGEWRITE hMsg;
						// Turn off the eye
						hMsg = g_pServerDE->StartMessage(m_hClient, SMSG_ALL_SEEING_EYE);
						g_pServerDE->WriteToMessageByte(hMsg, (DBYTE)nOff);
						g_pServerDE->WriteToMessageObject(hMsg, m_hObject);
    					g_pServerDE->EndMessage(hMsg);

						// Blind the Player 
						hMsg = g_pServerDE->StartMessage(m_hClient, SMSG_BLIND);
						g_pServerDE->WriteToMessageFloat(hMsg, (DFLOAT)10.0f);
						g_pServerDE->EndMessage2(hMsg, MESSAGE_GUARANTEED);
					}
				}
				
				if( bClearInv )
					pOwner->m_InventoryMgr.RemoveItem(INV_THEEYE);
			}
		}

		m_hOwner = DNULL;
		m_hClient = DNULL;
	}

  	g_pServerDE->RemoveObject( m_hObject );
}
    
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	SeeingEye::Save
//
//	PURPOSE:	Save the object
//
// ----------------------------------------------------------------------- //

void SeeingEye::Save(HMESSAGEWRITE hWrite, DDWORD dwSaveType)
{
	if (!hWrite) return;

	g_pServerDE->WriteToLoadSaveMessageObject(hWrite, m_hOwner);
	g_pServerDE->WriteToLoadSaveMessageObject(hWrite, m_hStuckObject);
	g_pServerDE->WriteToMessageByte(hWrite, m_bDropped);

}

// ----------------------------------------------------------------------- //
//
//	ROUTINE:	SeeingEye::Save
//
//	PURPOSE:	Save the object
//
// ----------------------------------------------------------------------- //

void SeeingEye::Load(HMESSAGEREAD hRead, DDWORD dwLoadType)
{
	if( !hRead ) return;

	g_pServerDE->ReadFromLoadSaveMessageObject(hRead, &m_hOwner);
	g_pServerDE->CreateInterObjectLink( m_hObject, m_hOwner );
	g_pServerDE->ReadFromLoadSaveMessageObject(hRead, &m_hStuckObject);
	if( m_hStuckObject )
		Attach( );
	m_bDropped = g_pServerDE->ReadFromMessageByte(hRead);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -