void CProjectile::AddImpact(HOBJECT hObj, LTVector vFirePos, LTVector vImpactPos, LTVector vSurfaceNormal, SurfaceType eType) { // Create the client side weapon fx... CLIENTWEAPONFX fxStruct; fxStruct.hFiredFrom = m_hFiredFrom; fxStruct.vSurfaceNormal = vSurfaceNormal; fxStruct.vFirePos = vFirePos; fxStruct.vPos = vImpactPos + (m_vDir * -1.0f); fxStruct.hObj = hObj; fxStruct.nWeaponId = m_pWeaponData->nId; fxStruct.nAmmoId = m_pAmmoData->nId; fxStruct.nSurfaceType = eType; fxStruct.wIgnoreFX = g_wIgnoreFX; // Always use the flash position for the first call to AddImpact... if (m_bNumCallsToAddImpact == 0) { fxStruct.vFirePos = m_vFlashPos; } // If we do multiple calls to AddImpact, make sure we only do some // effects once :) g_wIgnoreFX |= WFX_SHELL | WFX_LIGHT | WFX_MUZZLE; // Allow exit surface fx on the next call to AddImpact... g_wIgnoreFX &= ~WFX_EXITSURFACE; if (IsMoveable(hObj)) { // Well, don't do too many exit marks...The server will add one // if necessary... g_wIgnoreFX |= WFX_EXITMARK; } // If this is a player object, get the client id... if (IsPlayer(m_hFiredFrom)) { CPlayerObj* pPlayer = (CPlayerObj*) g_pLTServer->HandleToObject(m_hFiredFrom); if (pPlayer) { fxStruct.nShooterId = (uint8) g_pLTServer->GetClientID(pPlayer->GetClient()); } } CreateClientWeaponFX(fxStruct); // Do the area and progressive (over time) damage... if ((m_pAmmoData->nAreaDamage > 0.0f && eType != ST_SKY) || m_pAmmoData->fProgDamageLifetime > 0.0f) { AddExplosion(vImpactPos, vSurfaceNormal); } // Update Character fire info... if (m_hFiredFrom && IsCharacter(m_hFiredFrom) && CanSetLastFireInfo()) { CCharacter* pChar = (CCharacter*)g_pLTServer->HandleToObject(m_hFiredFrom); if (pChar) { CharFireInfo info; info.hObject = hObj; info.vFiredPos = m_vFlashPos; // Use initial flash pos info.vImpactPos = vImpactPos; info.nWeaponId = m_pWeaponData->nId; info.nAmmoId = m_pAmmoData->nId; info.fTime = g_pLTServer->GetTime(); info.bSilenced = m_bSilenced; info.eSurface = eType; pChar->SetLastFireInfo(&info); } } m_bNumCallsToAddImpact++; }
void Lock::HandleGadgetMsg(HOBJECT hSender, ConParse & parse) { if (parse.m_nArgs < 2 || !parse.m_Args[1]) return; AMMO* pAmmo = g_pWeaponMgr->GetAmmo(atol(parse.m_Args[1])); if (!pAmmo) return; LTBOOL bProcess = LTFALSE; if (m_bWeldable && pAmmo->eInstDamageType == DT_GADGET_WELDER) { bProcess = LTTRUE; } else if (m_bLightable && pAmmo->eInstDamageType == DT_GADGET_LIGHTER) { bProcess = LTTRUE; } else if (!m_bWeldable && pAmmo->eInstDamageType == DT_GADGET_LOCK_PICK) { bProcess = LTTRUE; } if (!bProcess) return; // Pick the lock by doing lock-pick damage to it... DamageStruct damage; damage.eType = pAmmo->eInstDamageType; damage.fDamage = GetRandom(m_fMinUnlockHitPts, m_fMaxUnlockHitPts); damage.vDir.Init(0, 1, 0); damage.hDamager = m_hObject; damage.DoDamage(this, m_hObject); // Play the lock pick sound... LTVector vPos; g_pLTServer->GetObjectPos(m_hObject, &vPos); if (m_hstrPickSnd) { char* pSound = g_pLTServer->GetStringData(m_hstrPickSnd); if (pSound) { g_pServerSoundMgr->PlaySoundFromPos(vPos, pSound, m_fSndRadius, SOUNDPRIORITY_MISC_MEDIUM); } } // Do fx for welding the lock... if (m_bWeldable && pAmmo->eInstDamageType == DT_GADGET_WELDER) { WEAPON* pWeapon = g_pWeaponMgr->GetWeapon("Lighter"); if (!pWeapon) return; SURFACE* pSurf = g_pSurfaceMgr->GetSurface("Metal"); if (!pSurf) return; LTVector vHisPos; g_pLTServer->GetObjectPos(hSender, &vHisPos); LTVector vDir = vHisPos - vPos; vDir.Norm(); CLIENTWEAPONFX fxStruct; fxStruct.hFiredFrom = hSender; fxStruct.vSurfaceNormal = vDir; fxStruct.vFirePos = vHisPos; fxStruct.vPos = vPos + vDir; fxStruct.hObj = m_hObject; fxStruct.nWeaponId = pWeapon->nId; fxStruct.nAmmoId = pAmmo->nId; fxStruct.nSurfaceType = pSurf->eType; // This should be a player object, get the client id... if (IsPlayer(hSender)) { CPlayerObj* pPlayer = (CPlayerObj*) g_pLTServer->HandleToObject(hSender); if (pPlayer) { fxStruct.nShooterId = (uint8) g_pLTServer->GetClientID(pPlayer->GetClient()); } } CreateClientWeaponFX(fxStruct); } }