Example #1
0
DDWORD Cat::ObjectMessageFn(HOBJECT hSender, DDWORD messageID, HMESSAGEREAD hRead)
{
	switch(messageID)
	{
		case MID_DAMAGE:
		{
			CServerDE* pServerDE = GetServerDE();
			if (!pServerDE) break;
			
			DVector vDir;
			pServerDE->ReadFromMessageVector(hRead, &vDir);
			DFLOAT fDamage   = pServerDE->ReadFromMessageFloat(hRead);
			DamageType eType = (DamageType)pServerDE->ReadFromMessageByte(hRead);
			HOBJECT hHeHitMe = pServerDE->ReadFromMessageObject(hRead);

			if (eType == DT_SQUEAKY)
			{
				if (m_hstrSqueakedAtSound)
				{
					char* pSound = pServerDE->GetStringData(m_hstrSqueakedAtSound);
					if (pSound) PlaySoundFromObject(m_hObject, pSound, m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM );
				}

				// If we're supposed to trigger something, trigger it here
	
				if (m_hstrSqueakyTarget && m_hstrSqueakyMessage)
				{
					SendTriggerMsgToObjects(this, m_hstrSqueakyTarget, m_hstrSqueakyMessage);
				}
			}
			else
			{
				if (m_hstrDeathSound)
				{
					DVector vPos;
					pServerDE->GetObjectPos(m_hObject, &vPos);
					char* pSound = pServerDE->GetStringData(m_hstrDeathSound);
					if (pSound) PlaySoundFromPos(&vPos, pSound, m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM );
				}

				if (m_hstrDeathTriggerTarget && m_hstrDeathTriggerMessage)
				{
					SendTriggerMsgToObjects(this, m_hstrDeathTriggerTarget, m_hstrDeathTriggerMessage);
				}

				pServerDE->RemoveObject(m_hObject);
			}
			break;
		}

		default : break;
	}

	return InventoryItem::ObjectMessageFn(hSender, messageID, hRead);
}
Example #2
0
void GameStartPoint::SendTrigger()
{
	if (!m_hstrTriggerTarget || !m_hstrTriggerMessage || !g_pServerDE)
		return;

	SendTriggerMsgToObjects(this, m_hstrTriggerTarget, m_hstrTriggerMessage);
}
Example #3
0
void PickupObject::PickedUp (HMESSAGEREAD hRead)
{
	// get the override respawn time - if it's -1.0, use the default

	float nRespawn = g_pServerDE->ReadFromMessageFloat (hRead);
	if (nRespawn == -1.0f) nRespawn = m_fRespawnTime;

	// make the item invisible for the correct amount of time

	DDWORD dwFlags = g_pServerDE->GetObjectFlags(m_hObject);
	g_pServerDE->SetObjectFlags(m_hObject, dwFlags & ~FLAG_VISIBLE & ~FLAG_TOUCH_NOTIFY );

	if( nRespawn <= 0.0f || g_pBloodServerShell->GetGameType() == GAMETYPE_SINGLE)
		g_pServerDE->RemoveObject( m_hObject );
	else
		g_pServerDE->SetNextUpdate(m_hObject, (DFLOAT) nRespawn);

	// Let the world know what happened...
		
	if (m_szPickupSound)
	{
		DVector vPos;
		g_pServerDE->GetObjectPos( m_hObject, &vPos );
		PlaySoundFromPos( &vPos, m_szPickupSound, 300.0f, SOUNDPRIORITY_MISC_HIGH);
	}

	// if we're supposed to trigger something, trigger it here
	
	if (m_hstrPickupTriggerTarget && m_hstrPickupTriggerMessage)
	{
		SendTriggerMsgToObjects(this, m_hstrPickupTriggerTarget, m_hstrPickupTriggerMessage);
	}
}
Example #4
0
void SoccerGoal::SendTrigger( )
{
	// Send the message
	if( m_hstrScoreTarget && m_hstrScoreMsg )
	{
		SendTriggerMsgToObjects( this, m_hstrScoreTarget, m_hstrScoreMsg );
	}
}
void CinematicTrigger::SendReplyMessage(int nReply)
{
	if (m_nCurMessage >= MAX_CT_MESSAGES) return;

    ILTCommon* pCommon = g_pLTServer->Common();
	if (!pCommon) return;

	CString	csTarget;
	CString csMsg;
	ConParse parse;

    char* pMsg = g_pLTServer->GetStringData(m_hstrRepliesTarget[m_nCurMessage]);
	if(!pMsg) return;

	parse.Init(pMsg);

    int i;
    for(i=0;i<nReply;i++)
	{
		if(pCommon->Parse(&parse) == LT_OK)
		{
			if(i == (nReply - 1))
			{
				if (parse.m_nArgs > 0 && parse.m_Args[0])
				{
					csTarget = parse.m_Args[0];
				}
				break;
			}
		}
	}

    pMsg = g_pLTServer->GetStringData(m_hstrRepliesMsg[m_nCurMessage]);
	if(!pMsg) return;

	parse.Init(pMsg);

	for(i=0;i<nReply;i++)
	{
		if(pCommon->Parse(&parse) == LT_OK)
		{
			if(i == (nReply - 1))
			{
				if (parse.m_nArgs > 0 && parse.m_Args[0])
				{
					csMsg = parse.m_Args[0];
				}
				break;
			}
		}
	}

	if (!csTarget.IsEmpty() && !csMsg.IsEmpty())
	{
		SendTriggerMsgToObjects(this, (char *)(LPCSTR)csTarget, (char *)(LPCSTR)csMsg);
	}
}
void CinematicTrigger::SendMessage()
{
	if (m_nCurMessage < MAX_CT_MESSAGES)
	{
		if (m_hstrTargetName[m_nCurMessage] && m_hstrMessageName[m_nCurMessage])
		{
            SendTriggerMsgToObjects(this, g_pLTServer->GetStringData( m_hstrTargetName[m_nCurMessage] ), g_pLTServer->GetStringData( m_hstrMessageName[m_nCurMessage] ));
		}
	}
}
Example #7
0
void WeaponItem::PickedUp(HMESSAGEREAD hRead)
{
	// make the item invisible for the correct amount of time

    uint32 dwFlags = g_pLTServer->GetObjectFlags(m_hObject);
    g_pLTServer->SetObjectFlags(m_hObject, dwFlags & ~FLAG_VISIBLE & ~FLAG_TOUCH_NOTIFY);

	// Let the world know what happened...

	PlayPickedupSound();


	// Clear our player obj, we no longer need this link...

    SetPlayerObj(LTNULL);


	// if we're supposed to trigger something, trigger it here

	if (m_hstrPickupTriggerTarget && m_hstrPickupTriggerMessage)
	{
		SendTriggerMsgToObjects(this, m_hstrPickupTriggerTarget, m_hstrPickupTriggerMessage);
	}


	// get the override respawn time - if it's -1.0, use the default

    LTFLOAT fRespawn = g_pLTServer->ReadFromMessageFloat (hRead);
	if (fRespawn == -1.0f) 
	{
		fRespawn = m_fRespawnDelay;
	}

	fRespawn /= g_RespawnScaleTrack.GetFloat(1.0f);

	if (g_pGameServerShell->GetGameType() != SINGLE && g_WeaponsStay.GetFloat() > 0.0f && m_fRespawnDelay > 0.0f)
    {
		fRespawn = 0.1f;
	}

	if (fRespawn <= 0.0f || g_pGameServerShell->GetGameType() == SINGLE)
	{
        g_pLTServer->RemoveObject(m_hObject);
	}
	else
	{
        g_pLTServer->SetNextUpdate(m_hObject, fRespawn);
	}
}
LTBOOL SendMixedTriggerMsgToObjects(LPBASECLASS pSender, HSTRING hName, HSTRING hMsg)
{
    uint32 cMsgs = 0;
    char* aszMsgs[256];

    ParseTriggerMsg(g_pLTServer->GetStringData(hMsg), aszMsgs, &cMsgs);

    LTBOOL bReturn = LTTRUE;
    for ( uint32 iMsg = 0 ; iMsg < cMsgs ; iMsg++ )
    {
        bReturn &= SendTriggerMsgToObjects(pSender, g_pLTServer->GetStringData(hName), aszMsgs[iMsg]);
    }

    return bReturn;
}
LTBOOL SendMixedTriggerMsgToObjects(LPBASECLASS pSender, const char* pName, const char* pMsg)
{
    uint32 cMsgs = 0;
    char* aszMsgs[256];

    ParseTriggerMsg(pMsg, aszMsgs, &cMsgs);

    LTBOOL bReturn = LTTRUE;
    for ( uint32 iMsg = 0 ; iMsg < cMsgs ; iMsg++ )
    {
        bReturn &= SendTriggerMsgToObjects(pSender, pName, aszMsgs[iMsg]);
    }

    return bReturn;
}
LTBOOL SendTriggerMsgToObjects(LPBASECLASS pSender, HSTRING hName, HSTRING hMsg)
{
    if (!hMsg) return LTFALSE;

    char* pMsg = g_pLTServer->GetStringData(hMsg);

    // Process the message as a command if it is a valid command...

    if (g_pCmdMgr->IsValidCmd(pMsg))
    {
        return g_pCmdMgr->Process(pMsg);
    }

    if (!hName) return LTFALSE;

    char* pName = g_pLTServer->GetStringData(hName);

    return SendTriggerMsgToObjects(pSender, pName, pMsg);
}
Example #11
0
bool Group::OnTrigger(HOBJECT hSender, const CParsedMsg &cMsg)
{
	// Put the message back in a string
	char aMsgBuff[256];
	cMsg.ReCreateMsg(aMsgBuff, sizeof(aMsgBuff), 0);

	const char* pName;
	for (uint32 i=0; i < m_nNumTargets; i++)
	{
		if (m_hstrObjectNames[i])
		{
            pName = g_pLTServer->GetStringData(m_hstrObjectNames[i]);
			if (pName && pName[0])
			{
				SendTriggerMsgToObjects(this, pName, aMsgBuff);
			}
		}
	}

	return true;
}
Example #12
0
void CDestructable::HandleDestruction()
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	if (m_hstrDeathTriggerTarget)
	{
		LPBASECLASS pD = pServerDE->HandleToObject(m_hObject);
		SendTriggerMsgToObjects(pD, m_hstrDeathTriggerTarget, m_hstrDeathTriggerMessage);
	}

	// See if we need to spawn anything
	if (m_hstrSpawnObject)
	{
		DVector vPos;
		DRotation rRot;

		pServerDE->GetObjectPos(m_hObject, &vPos);
		pServerDE->GetObjectRotation(m_hObject, &rRot);

		SpawnObject(pServerDE->GetStringData(m_hstrSpawnObject), &vPos, &rRot, &m_vSpawnObjectVel);
	}
}
void CinematicTrigger::HandleOff()
{
	if (!m_bOn) return;

	for ( uint32 iWho = 0 ; iWho < MAX_CT_MESSAGES; iWho++ )
	{
		if ( m_hstrWhoPlaysDialogue[iWho] )
		{
			HOBJECT hWho;
			if ( LT_OK == FindNamedObject(m_hstrWhoPlaysDialogue[iWho], hWho) )
			{
				if ( IsKindOf(hWho, "CAI") )
				{
					CAI* pAI = (CAI*)g_pLTServer->HandleToObject(hWho);
					pAI->UnlinkCinematicTrigger(m_hObject);
				}
			}
		}
	}

    m_bOn = LTFALSE;

	// If we have a current speaker, make sure he is done talking...

	if (m_hCurSpeaker)
	{
        CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(m_hCurSpeaker);
		if (pChar)
		{
			pChar->StopDialogue();
		}

		// Clear our speaker...

        g_pLTServer->BreakInterObjectLink(m_hObject, m_hCurSpeaker);
        m_hCurSpeaker = LTNULL;
	}

	// Clear out our last speaker

	if (m_hLastSpeaker)
	{
        CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(m_hLastSpeaker);
		if (pChar)
		{
			pChar->StopDialogue(TRUE);
		}
        g_pLTServer->BreakInterObjectLink(m_hObject, m_hLastSpeaker);
        m_hLastSpeaker = LTNULL;
	}


	// Send the clean up trigger message...

	if (m_hstrCleanUpTriggerTarget && m_hstrCleanUpTriggerMsg)
	{
        SendTriggerMsgToObjects(this, g_pLTServer->GetStringData( m_hstrCleanUpTriggerTarget ), g_pLTServer->GetStringData( m_hstrCleanUpTriggerMsg ));
	}

	// Turn off the camera...

	if (m_hCamera && !m_bLeaveCameraOn)
	{
		SendTriggerMsgToObject(this, m_hCamera, FALSE, "OFF");
	}

	// Turn off the keyframer...

	if (m_hKeyFramer)
	{
		SendTriggerMsgToObject(this, m_hKeyFramer, FALSE, "OFF");
	}

    SetNextUpdate(m_hObject, 0.0f);

	if (m_bOneTimeOnly)
	{
		// Can't get rid of object if we're leaving the camera on ;)...

		if (!m_hCamera || !m_bLeaveCameraOn)
		{
			g_pLTServer->RemoveObject(m_hObject);
		}
	}
}
LTBOOL CinematicTrigger::Update()
{
    if (!g_pLTServer) return LTFALSE;

    SetNextUpdate(m_hObject, 0.001f);

    LTBOOL bDialogueDone = !m_bDialogueDone ? !UpdateDialogue() : m_bDialogueDone;

	// If we created a camera and it is done end the cinematic...

	if (m_bCreateCamera)
	{
		if (!m_hCamera)
		{
			HandleOff();
		}
		else
		{
            uint32 dwUsrFlags = g_pLTServer->GetObjectUserFlags(m_hCamera);
			if ( !(dwUsrFlags & USRFLG_CAMERA_LIVE) )
			{
				HandleOff();
			}
		}
	}

	// If the dialog is done and the keyframer is finished end the cinematic...

	if (bDialogueDone)
	{
		if (!m_bDialogueDone)
		{
            m_bDialogueDone = LTTRUE;

			// Send trigger...

			if (m_hstrDialogueDoneTarget && m_hstrDialogueDoneMsg)
			{
                SendTriggerMsgToObjects(this, g_pLTServer->GetStringData(m_hstrDialogueDoneTarget), g_pLTServer->GetStringData(m_hstrDialogueDoneMsg));
			}
		}

		if (m_hKeyFramer)
		{
            KeyFramer* pKeyFramer = (KeyFramer*)g_pLTServer->HandleToObject(m_hKeyFramer);
			if (!pKeyFramer || pKeyFramer->m_bFinished)
			{
				HandleOff();
			}
		}
		else
		{
			if (!m_hCamera)
			{
				HandleOff();
			}
		}
	}

    return LTTRUE;
}
LTBOOL CinematicTrigger::StartDialogue(int nDecision)
{
	if(m_nCurMessage >= MAX_CT_MESSAGES)
        return LTFALSE;

	CString csDialogue;
	CString	csTarget;
	CString csChar;
    uint8 byMood = 0;

	if(nDecision)
	{
        char* pMsg = g_pLTServer->GetStringData(m_hstrReplies[m_nCurMessage]);
		if(!pMsg) return FALSE;

        ILTCommon* pCommon = g_pLTServer->Common();
		if (!pCommon) return FALSE;

		ConParse parse;
		parse.Init(pMsg);

		for(int i=0;i<nDecision;i++)
		{
			if(pCommon->Parse(&parse) == LT_OK)
			{
				if (parse.m_nArgs < 2)
				{
					if (parse.m_nArgs < 1 || stricmp(parse.m_Args[0], "NONE") != 0)
					{
                        g_pLTServer->CPrint("Cinematic Trigger - ERROR - Not enough replies for the amount of decisions!");
						TRACE("Cinematic Trigger - ERROR - Not enough replies for the amount of decisions!\n");
						return FALSE;
					}
				}
				else if(i == (nDecision - 1))
				{
					csTarget = parse.m_Args[0];
					if(csTarget.Compare("Cinematic") == 0)
					{
						//HandleOff(); - Should be done by reply message?

						// Force the dialogue to be done...
						m_nCurMessage = MAX_CT_MESSAGES;

						// We have another cinematic to play, turn it on...
						SendTriggerMsgToObjects(this, parse.m_Args[1], "ON");
						return FALSE;
					}
					else
					{
						// Look at the second argument to determine if we have a
						// character override
						if((parse.m_Args[1][0] < '0') && (parse.m_Args[1][0] > '9'))
						{
							// We have a character override
							csChar = parse.m_Args[1];
							csDialogue = parse.m_Args[2];
							// Check for a mood
							if(parse.m_nArgs == 4)
							{
								// char charoverride id mood
								byMood = atoi(parse.m_Args[3]);
							}
						}
						else
						{
							// We don't have a character override
							csDialogue = parse.m_Args[1];
							// check for a mood
							if(parse.m_nArgs == 3)
							{
								// char id mood
								byMood = atoi(parse.m_Args[2]);
							}
						}
					}
				}
			}
		}
	}
	else
	{
		// Send the message here

		SendMessage();

		// Check for an initial message

		if (m_nCurMessage == 0)
		{
			if (m_hstrDialogueStartTarget && m_hstrDialogueStartMsg)
			{
                SendTriggerMsgToObjects(this, g_pLTServer->GetStringData(m_hstrDialogueStartTarget), g_pLTServer->GetStringData(m_hstrDialogueStartMsg));
			}
		}

        csDialogue = g_pLTServer->GetStringData(m_hstrDialogue[m_nCurMessage]);
        csTarget = g_pLTServer->GetStringData(m_hstrWhoPlaysDialogue[m_nCurMessage]);
	}

	if (csDialogue.IsEmpty())
	{
		// Make sure the reply messages are sent, even if we aren't going to
		// do any dialogue...

		if (nDecision)
		{
			SendReplyMessage(nDecision);
		}

        return LTFALSE;
	}

	const char *szCharOverride = NULL;
	if(csChar.IsEmpty())
	{
		int nSpace = csTarget.Find(' ');
		if(nSpace != -1)
		{
			// There is a space in the name, therefore we have a character override
			csChar = csTarget.Right(csTarget.GetLength()-nSpace-1);
			csTarget = csTarget.Left(nSpace);
			if(!csChar.IsEmpty())
				szCharOverride = csChar;
		}
	}
	else
	{
		szCharOverride = csChar;
	}


    HOBJECT hObj = !csTarget.IsEmpty() ? PlayedBy((char *)(LPCSTR)csTarget) : LTNULL;
	if (hObj)
	{
        CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(hObj);
		if (pChar)
		{
			char *szDecisions = NULL;
			if (!nDecision && m_hstrDecisions[m_nCurMessage])
            {
				szDecisions = g_pLTServer->GetStringData(m_hstrDecisions[m_nCurMessage]);
			}

			// See if there's a windowed message next
			int nNext = m_nCurMessage + 1;
			//BOOL bStayOpen = (szDecisions || ((nNext < MAX_CT_MESSAGES) && m_hstrDialogue[nNext] && m_bWindow[nNext] && (m_fDelay[nNext] == 0.0f)));
			//BOOL bWindow = m_bWindow[m_nCurMessage];

            BOOL bStayOpen = LTFALSE;
			BOOL bWindow = (BOOL)szDecisions;

			pChar->PlayDialogue((char *)(LPCSTR)csDialogue,this,bWindow,bStayOpen,szCharOverride,szDecisions,byMood);

			SetupLinks(hObj);

            return LTTRUE;
		}
	}
    return LTFALSE;
}
Example #16
0
void CDestructable::HandleDamage(HOBJECT hSender, HMESSAGEREAD hRead)
{
	CServerDE* pServerDE = BaseClass::GetServerDE();
	if (!pServerDE) return;

	DVector vDir,vPos;

	pServerDE->ReadFromMessageVector(hRead, &vDir);
	DFLOAT fDamage = pServerDE->ReadFromMessageFloat(hRead);
	DBYTE nDamageType	= pServerDE->ReadFromMessageByte(hRead);
	HOBJECT hWhoHit = pServerDE->ReadFromMessageObject(hRead);
	pServerDE->ReadFromMessageVector(hRead, &vPos);

//	char buf[50];
	DFLOAT fOldHitPoints = m_fHitPoints;
	fDamage = fDamage * m_fResistance;

	// Just return if we can't take damage
	if (m_bGodMode || (m_bTriggerOnly && nDamageType != DAMAGE_TYPE_DEATH) || fDamage < 0)
	{
		return;
	}

	if (!IsPlayerToPlayerDamageOk(hSender, hWhoHit))
	{
		return;
	}

	// If instant death, don't bother calculating stuff.. 
	if( m_bDestructable && nDamageType == DAMAGE_TYPE_DEATH)
	{
		m_fArmorPoints = 0;
		m_fHitPoints = 0;
		m_fDeathHitPoints = 0;
		m_fLastDamagePercent = 100.0f;
		m_fLastDamageAmount = (DFLOAT)m_fMaxHitPoints;

		nDamageType &= 0x0f;	// Mask off the damage type flags
		m_nLastDamageType = nDamageType;
	}
	else
	{
		// Special pre-damage base character modifiers
		if (IsAICharacter(m_hObject))
		{
			m_nNodeHit = CalculateHitLimb(vDir,vPos,fDamage);

			if(m_nNodeHit == -1 && !(nDamageType & DAMAGE_TYPE_NORMAL))
				m_nNodeHit = SetProperNode(pServerDE->IntRandom(0,NUM_ALL_NODES - 3));
			else if(m_nNodeHit >= 0)
				m_nNodeHit = SetProperNode(m_nNodeHit);
			else
				return;

			//Compute one side got hit for recoils
			DVector vU, vR, vF, vTmpDir;
			DRotation rRot;
			pServerDE->GetObjectRotation(m_hObject, &rRot);
			pServerDE->GetRotationVectors(&rRot, &vU, &vR, &vF);

			VEC_COPY(vTmpDir, vDir);

			VEC_MULSCALAR(vTmpDir,vTmpDir,-1.0f);
			DFLOAT fAmount = (DFLOAT) atan2(vTmpDir.x, vTmpDir.z);    
			DFLOAT fAmount2 = (DFLOAT) atan2(vF.x, vF.z);

			if(fAmount < 0.0f)
				fAmount = (MATH_PI*2) + fAmount;
			if(fAmount2 < 0.0f)
				fAmount2 = (MATH_PI*2) + fAmount2;

			DFLOAT fAngle = fAmount2 - fAmount;

			if(fAngle <= MATH_PI/2 || fAngle >= 3*MATH_PI/2)	//Hit the front
			{
				m_nSideHit = 0;
			}
			else //Hit the back
			{
				m_nSideHit = 6;	
			}

			if (m_hLastDamager)
				pServerDE->BreakInterObjectLink(m_hObject, m_hLastDamager);

			m_hLastDamager = hWhoHit;

			if(m_hLastDamager)
				pServerDE->CreateInterObjectLink(m_hObject, m_hLastDamager);

			if(m_nNodeHit == NODE_NECK)
			{
				AI_Mgr* pAI = (AI_Mgr*)pServerDE->HandleToObject(m_hObject);

				if(pAI->m_bCabal || pServerDE->IsKindOf(pServerDE->GetObjectClass(m_hObject), pServerDE->GetClass("SoulDrudge")))
					m_fHitPoints = 0;
				
				fDamage *= 1.5f;
			}
			else if(m_nNodeHit == NODE_TORSO)
			{
				fDamage *= 1.0f;
			}
			else
			{
				fDamage *= 0.5f;
			}
		}

		if (IsBaseCharacter(m_hObject))
		{
			CBaseCharacter *pOwner = (CBaseCharacter*)pServerDE->HandleToObject(m_hObject);

//			if (pOwner->IsItemActive(SPELL_STONE))
//				return;

			// If Nigh-invulnerability powerup in effect..
			if (m_bNighInvulnerable)
				fDamage = fDamage * 0.05f;

			// Shield absorbs the damage as Focus ammo use
/*			if (nDamageType != DAMAGE_TYPE_DEATH && pOwner->IsItemActive(SPELL_SHIELD))
			{
				DFLOAT fFocusAmmo = pOwner->GetInventoryMgr()->GetAmmoCount(AMMO_FOCUS);
		
				fFocusAmmo -= fDamage;

				if (fFocusAmmo < 0.0f)
				{
					fDamage = -fFocusAmmo;
					fFocusAmmo = 0.0f;
				}
				else
				{
					fDamage = 0.0f;
				}

				pOwner->GetInventoryMgr()->SetAmmoCount(AMMO_FOCUS, fFocusAmmo);
			}
*/
			// Reflection reflects damage back to the sender, and absorbs 
			// twice the damage in focus ammo
/*			if (pOwner->IsItemActive(SPELL_REFLECTION) && !(nDamageType & DAMAGE_FLAG_AREAEFFECT))
			{
				DFLOAT fFocusAmmo = pOwner->GetInventoryMgr()->GetAmmoCount(AMMO_FOCUS);
		
				fFocusAmmo -= fDamage * 2.0f;

				if (fFocusAmmo < 0.0f)
				{
					fDamage = -fFocusAmmo / 2.0f;
					fFocusAmmo = 0.0f;
				}
				else
				{
					fDamage = 0.0f;
				}

				pOwner->GetInventoryMgr()->SetAmmoCount(AMMO_FOCUS, fFocusAmmo);
			}
*/
		}

		// If single player, don't let the player apply damage to himself.
		if (m_bApplyDamagePhysics && !(g_pBloodServerShell->GetGameType() == GAMETYPE_SINGLE && (m_hObject == hWhoHit) && IsPlayer(m_hObject)))
			ApplyDamagePhysics(fDamage, &vDir);
		
		// Can't damage if already dead...

		if( m_bDestructable && m_bDead )
			return;

		if( m_bDestructable && m_fArmorPoints > 0.0 && nDamageType != DAMAGE_TYPE_SUFFOCATE )
		{
			DFLOAT fAbsorb = 0.0f;

			if (m_fArmorPoints <= 25.0f)
				fAbsorb = fDamage * 0.3f;
			else if (m_fArmorPoints <= 50.0f)
				fAbsorb = fDamage * 0.5f;
			else if (m_fArmorPoints <= 100.0f)
				fAbsorb = fDamage * 0.7f;
			else if (m_fArmorPoints <= 150.0f)
				fAbsorb = fDamage * 0.8f;
			else 
				fAbsorb = fDamage * 0.9f;

			if (!m_bGodMode)
			{
				m_fArmorPoints -= fAbsorb;
				if (m_fArmorPoints < 0.0f) 
				{
					fAbsorb += m_fArmorPoints;
					m_fArmorPoints = 0.0f;
				}
        
				fDamage -= fAbsorb;
       		}
		}

		if (fDamage < 0.0f) fDamage = 0.0f;	// just to be sure :)

		// Save damage type so entity will know how to react
		nDamageType &= 0x0f;	// Mask off the damage type flags
		if (fDamage) m_nLastDamageType = nDamageType;

		if( m_bDestructable )
		{
			m_fHitPoints -= fDamage;
			m_fDeathHitPoints -= fDamage;
		}
	}
	// 01/13/98  How much damage was done (percentage of max hit points)
	m_fLastDamagePercent += (DFLOAT)fDamage/(DFLOAT)GetMaxHitPoints();
	m_fLastDamageAmount += fDamage;
	VEC_COPY(m_vLastDamageDirection, vDir);

	// Set pSender if sender is a player
	CPlayerObj* pSender = DNULL;

	if( m_bDestructable )
	{
		if(hWhoHit)
			if(pServerDE->IsKindOf(pServerDE->GetObjectClass(hWhoHit), pServerDE->GetClass("CPlayerObj")))
				pSender = (CPlayerObj*)pServerDE->HandleToObject(hWhoHit);

		// If it was hurt with a leech weapon, then add the damage done back to playerobj
		if(pSender && pServerDE->IsKindOf(pServerDE->GetObjectClass(m_hObject), pServerDE->GetClass("CBaseCharacter")))
		{
			if(nDamageType == DAMAGE_TYPE_LEECH)
			{
				if (!pSender->IsDead() && !pSender->IsInSlowDeath())
				{
					pSender->GetDestructable()->Heal(fDamage / 10.0f);
				}
			}
		}
	}

//	m_fHitPoints = 1;
	if( m_bDestructable && m_fHitPoints <= 0 )
	{
		m_bDead = DTRUE;
		m_fHitPoints = 0;
		HandleDestruction();

		m_hWhoKilledMeLast = hWhoHit;

        // If its a PlayerObj then Increase the Kills 
/*		if(pSender && pServerDE->IsKindOf(pServerDE->GetObjectClass(m_hObject), pServerDE->GetClass("CBaseCharacter"))) 
		{
            // If it was killed with a melee weapon, then add the damage done back to playerobj
        	if(nDamageType == DAMAGE_TYPE_LEECH)
            {
				pSender->GetDestructable()->Heal(fDamage / 5.0f);
				pSender->AddMeleeKill();

				DFLOAT fIncrease = 0.0f;
				int nKills = pSender->GetMeleeKills();
        
				if (nKills > 0)
				{
                    // Increase Damage by 5% for every kill
                    fIncrease = (DFLOAT)nKills * .05f;
                    // Max Increase 200%
                    if (fIncrease > 2.0f)   fIncrease = 2.0f;
                }            
                
                // If the Increase is greater than 50% then add back some of the damage to player
                if (fIncrease > 0.5f)
                {
                    // Add back damage to playerobj
                    DFLOAT fAddHits = fDamage * (fIncrease/2.0f);
                    
    				pSender->GetDestructable()->Heal(fAddHits);
                    
                    // Need to Glow the player Sword...
                    // Set Glow on the Melee Weapon
                    
                }
            }
        }*/
	}


	// If this is supposed to send a damage trigger, send it now..

	if( m_bDestructable && m_hstrDamageTriggerTarget && m_hstrDamageTriggerMessage )
	{
		LPBASECLASS pD = pServerDE->HandleToObject(m_hObject);
		SendTriggerMsgToObjects(pD, m_hstrDamageTriggerTarget, m_hstrDamageTriggerMessage);
	}

	// If player did this damage and has soul stealing binding..
	if( m_bDestructable && fOldHitPoints != m_fHitPoints && m_hObject != hWhoHit)
	{
		// Make sure it's a player
		if(pSender) 
		{
			DFLOAT fHeal;
			if (pSender->HasSoulStealingBinding() && (fHeal = (fOldHitPoints - m_fHitPoints) / 10.0f))
			{
				pSender->GetDestructable()->Heal(fHeal);
			}
		}
	}
}
Example #17
0
void Trigger::Activate()
{
	CServerDE* pServerDE = GetServerDE();
	if (!pServerDE) return;


	// Make us wait a bit before we can be triggered again...

	if (m_bTimedTrigger)
	{
		pServerDE->SetNextUpdate(m_hObject, UPDATE_DELTA);
		pServerDE->SetDeactivationTime(m_hObject, 0.0f);
	}
	else
	{
		pServerDE->SetNextUpdate(m_hObject, m_fTriggerDelay);
		pServerDE->SetDeactivationTime(m_hObject, 0.0f);
	}
	
	
	// If this is a counter trigger, determine if we can activate or not...

	if (++m_nCurrentActivation < m_nActivationCount)
	{
		return;
	}
	else
	{
		m_nCurrentActivation = 0;
	}


	if (m_hstrActivationSound)
	{
		char* pSound = pServerDE->GetStringData(m_hstrActivationSound);
		if (pSound && pSound[0] != '\0')
		{
			PlaySoundFromObject(m_hObject, pSound, m_fSoundRadius, SOUNDPRIORITY_MISC_HIGH);
		}
	}

	DBOOL bTriggerMsg1 = DTRUE;
	DBOOL bTriggerMsg2 = DTRUE;

	if (m_bWeightedTrigger)
	{
		bTriggerMsg1 = (GetRandom(0.0f, 1.0f) < m_fMessage1Weight ? DTRUE : DFALSE);
		bTriggerMsg2 = !bTriggerMsg1;
	}

	for (int i=0; i < MAX_NUM_MESSAGES; i++)
	{
		DBOOL bOkayToSend = DTRUE;

		if (i == 0 && !bTriggerMsg1) bOkayToSend = DFALSE;
		else if (i == 1 && !bTriggerMsg2) bOkayToSend = DFALSE;

		if (bOkayToSend && m_hstrTargetName[i] && m_hstrMessageName[i])
		{
			SendTriggerMsgToObjects(this, m_hstrTargetName[i], m_hstrMessageName[i]);
		}
	}

	if (m_bTouchNotifyActivation && m_hTouchObject && m_bTriggerTouch && m_hstrMessageTouch)
	{
		SendTriggerMsgToObject(this, m_hTouchObject, m_hstrMessageTouch);
		m_bTouchNotifyActivation = DFALSE;
		m_hTouchObject = DNULL;
	}
}
Example #18
0
CScanner::DetectState CScanner::UpdateDetect()
{
	CCharacter* pChar   = g_pCharacterMgr->LookForEnemy(this);
	CDeathScene* pScene = g_pCharacterMgr->LookForDeathScene(this);

	if (pChar || pScene)
	{


		// Set the focus timer if it hasn't been set...(i.e., the
		// first time we see a "situation")...

        LTBOOL bFocus = !!(GetFocusTime() > 0.0f);

		if (bFocus && !m_FocusTimer.GetDuration())
		{
			m_FocusTimer.Start(GetFocusTime());
		}
		else if (!bFocus || m_FocusTimer.Stopped())
		{
			// Only process detection once (unless it is reset
			// someplace else...)...

			if (m_bCanProcessDetection)
			{
				if (pChar)
				{
					SetLastDetectedEnemy(pChar->m_hObject);
				}
				else if (pScene)
				{
					SetLastDetectedDeathPos(pScene->GetPosition());
				}

				SendTriggerMsgToObjects(this, m_hstrSpotTarget, m_hstrSpotMessage);

                m_bCanProcessDetection = LTFALSE;
			}

			return DS_DETECTED;
		}

		return DS_FOCUSING;
	}
	else
	{
		// If the focus timer has stopped (i.e., we tried to focus on
		// a character but he moved before we detected him, stop the
		// timer (which will reset the duration)...

		if (m_FocusTimer.Stopped())
		{
			m_FocusTimer.Stop();
		}
		else
		{
			return DS_FOCUSING;
		}
	}

	return DS_CLEAR;
}