void CxStatic::OnRButtonDown(UINT nFlags, CPoint point) { if (IsMoveable() == TRUE) { m_point = point; CRect rect; GetWindowRect( rect ); ScreenToClient( rect ); m_pTrack = new CRectTracker(&rect, CRectTracker::dottedLine | CRectTracker::resizeInside | CRectTracker::hatchedBorder); // RIGHT-CLICK + CONTROL if (nFlags & MK_CONTROL){ GetWindowRect(rect); GetParent()->ScreenToClient(rect); m_pTrack->TrackRubberBand(GetParent(), rect.TopLeft()); m_pTrack->m_rect.NormalizeRect(); } else { m_pTrack->Track(GetParent(), point); } rect = LPRECT(m_pTrack->m_rect); MoveWindow(&rect,TRUE);//Move Window to our new position // Clean our mess if (m_pTrack) delete m_pTrack; rect = NULL; } CStatic::OnRButtonDown(nFlags, point); }
void CPhysicsObject::ApplyTorqueCenter(const AngularImpulse &torque) { if (!IsMoveable() || !IsMotionEnabled()) { return; } Wake(); btVector3 bullTorque; ConvertAngularImpulseToBull(torque, bullTorque); m_pObject->applyTorqueImpulse(bullTorque); }
void TAbstractWindow::_handle_mouseMove( const TEvent_MouseMoved& event, bool& consume ) { if ((IsMoveable() == true) && (state == State::Moving)) { SetPosition(event.x - clickPosition.x, event.y - clickPosition.y); } consume = false; }
void TAbstractWindow::_handle_mouseButtonReleased( const TEvent_MouseClick& event, bool& consume ) { if ((IsMoveable() == true) && (state == State::Moving)) { SetPosition(event.x - clickPosition.x, event.y - clickPosition.y); state = State::Normal; } consume = false; }
void TAbstractWindow::_handle_mouseButtonPressed( const TEvent_MouseClick& event, bool& consume ) { if ((IsMoveable() == true) && (_isMouseOverHeader() == true)) { clickPosition.x = event.x - GetScreenPosition().x; clickPosition.y = event.y - GetScreenPosition().y; state = State::Moving; } consume = false; }
void CPhysicsObject::SetVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) { Assert(IsMoveable()); if ( !IsMoveable() ) return; IVP_Core *core = m_pObject->get_core(); Wake(); if ( velocity ) { ConvertPositionToIVP( *velocity, core->speed_change ); core->speed.set_to_zero(); } if ( angularVelocity ) { ConvertAngularImpulseToIVP( *angularVelocity, core->rot_speed_change ); core->rot_speed.set_to_zero(); } }
void CPhysicsObject::ApplyForceCenter(const Vector &forceVector) { if (!IsMoveable() || !IsMotionEnabled()) { return; } Wake(); // forceVector is in kg*in/s*time // bullet takes forces in newtons, aka kg*m/s*time btVector3 force; ConvertForceImpulseToBull(forceVector, force); m_pObject->applyCentralImpulse(force); }
void CPhysicsObject::ApplyTorqueCenter( const AngularImpulse &torqueImpulse ) { //Assert(IsMoveable()); if ( !IsMoveable() ) return; IVP_U_Float_Point ivpTorque; ConvertAngularImpulseToIVP( torqueImpulse, ivpTorque ); IVP_Core *core = m_pObject->get_core(); core->async_rot_push_core_multiple_ws( &ivpTorque, 1.0 ); core->rot_speed_change.k[0] = clamp( core->rot_speed_change.k[0], -MAX_ROT_SPEED, MAX_ROT_SPEED ); core->rot_speed_change.k[1] = clamp( core->rot_speed_change.k[1], -MAX_ROT_SPEED, MAX_ROT_SPEED ); core->rot_speed_change.k[2] = clamp( core->rot_speed_change.k[2], -MAX_ROT_SPEED, MAX_ROT_SPEED ); Wake(); }
// UNDONE: Limit these? void CPhysicsObject::AddVelocity( const Vector *velocity, const AngularImpulse *angularVelocity ) { Assert(IsMoveable()); if ( !IsMoveable() ) return; IVP_Core *core = m_pObject->get_core(); Wake(); if ( velocity ) { IVP_U_Float_Point ivpVelocity; ConvertPositionToIVP( *velocity, ivpVelocity ); core->speed_change.add( &ivpVelocity ); } if ( angularVelocity ) { IVP_U_Float_Point ivpAngularVelocity; ConvertAngularImpulseToIVP( *angularVelocity, ivpAngularVelocity ); core->rot_speed_change.add(&ivpAngularVelocity); } }
void CPhysicsObject::ApplyForceOffset(const Vector &forceVector, const Vector &worldPosition) { if (!IsMoveable() || !IsMotionEnabled()) { return; } Wake(); Vector local; WorldToLocal(&local, worldPosition); btVector3 force, offset; ConvertForceImpulseToBull(forceVector, force); ConvertPosToBull(local, offset); m_pObject->applyImpulse(force, offset); Wake(); }
// Apply force impulse (momentum) to the object void CPhysicsObject::ApplyForceCenter( const Vector &forceVector ) { // Assert(IsMoveable()); if ( !IsMoveable() ) return; IVP_U_Float_Point tmp; ConvertForceImpulseToIVP( forceVector, tmp ); IVP_Core *core = m_pObject->get_core(); tmp.mult( core->get_inv_mass() ); tmp.k[0] = clamp( tmp.k[0], -MAX_SPEED, MAX_SPEED ); tmp.k[1] = clamp( tmp.k[1], -MAX_SPEED, MAX_SPEED ); tmp.k[2] = clamp( tmp.k[2], -MAX_SPEED, MAX_SPEED ); m_pObject->async_add_speed_object_ws( &tmp ); }
void CPhysicsObject::AddVelocity(const Vector *velocity, const AngularImpulse *angularVelocity) { if (!velocity && !angularVelocity) return; if (!IsMoveable() || !IsMotionEnabled()) { return; } Wake(); btVector3 bullvelocity, bullangular; if (velocity) { ConvertPosToBull(*velocity, bullvelocity); m_pObject->setLinearVelocity(m_pObject->getLinearVelocity() + bullvelocity); } // Angular velocity is supplied in local space. if (angularVelocity) { ConvertAngularImpulseToBull(*angularVelocity, bullangular); bullangular = m_pObject->getWorldTransform().getBasis() * bullangular; m_pObject->setAngularVelocity(m_pObject->getAngularVelocity() + bullangular); } }
void CPhysicsObject::ApplyForceOffset( const Vector &forceVector, const Vector &worldPosition ) { // Assert(IsMoveable()); if ( !IsMoveable() ) return; IVP_U_Point pos; IVP_U_Float_Point force; ConvertForceImpulseToIVP( forceVector, force ); ConvertPositionToIVP( worldPosition, pos ); IVP_Core *core = m_pObject->get_core(); core->async_push_core_ws( &pos, &force ); core->speed_change.k[0] = clamp( core->speed_change.k[0], -MAX_SPEED, MAX_SPEED ); core->speed_change.k[1] = clamp( core->speed_change.k[1], -MAX_SPEED, MAX_SPEED ); core->speed_change.k[2] = clamp( core->speed_change.k[2], -MAX_SPEED, MAX_SPEED ); core->rot_speed_change.k[0] = clamp( core->rot_speed_change.k[0], -MAX_ROT_SPEED, MAX_ROT_SPEED ); core->rot_speed_change.k[1] = clamp( core->rot_speed_change.k[1], -MAX_ROT_SPEED, MAX_ROT_SPEED ); core->rot_speed_change.k[2] = clamp( core->rot_speed_change.k[2], -MAX_ROT_SPEED, MAX_ROT_SPEED ); Wake(); }
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 CreateClientWeaponFX(CLIENTWEAPONFX & theStruct) { if (!g_pLTServer) return; // If this is a moveable object, set the flags of fx to ignore // marks and smoke... if (IsMoveable(theStruct.hObj)) { theStruct.wIgnoreFX |= WFX_MARK; // Create a server-side mark if applicable... if (CanMarkObject(theStruct.hObj)) { AMMO* pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId); if (pAmmo) { if (pAmmo->pImpactFX) { if (WFX_MARK & pAmmo->pImpactFX->nFlags) { CreateServerMark((CLIENTWEAPONFX)theStruct); } } // Create an exit mark if applicable... if (pAmmo->pFireFX) { if (WFX_EXITMARK & pAmmo->pFireFX->nFlags) { CreateServerExitMark((const CLIENTWEAPONFX)theStruct); } } } } } // Do impact dings if applicable... if (!(IsMultiplayerGame() && IsCharacter(theStruct.hObj))) { theStruct.wIgnoreFX |= WFX_IMPACTDING; } // Tell all the clients who can see this fx about the fx... HMESSAGEWRITE hMessage = g_pLTServer->StartInstantSpecialEffectMessage(&(theStruct.vPos)); g_pLTServer->WriteToMessageByte(hMessage, SFX_WEAPON_ID); g_pLTServer->WriteToMessageObject(hMessage, theStruct.hFiredFrom); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nWeaponId); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nAmmoId); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nSurfaceType); g_pLTServer->WriteToMessageWord(hMessage, theStruct.wIgnoreFX); g_pLTServer->WriteToMessageByte(hMessage, theStruct.nShooterId); g_pLTServer->WriteToMessageVector(hMessage, &(theStruct.vFirePos)); g_pLTServer->WriteToMessageVector(hMessage, &(theStruct.vPos)); g_pLTServer->WriteToMessageVector(hMessage, &(theStruct.vSurfaceNormal)); // This doesn't always work correctly... //g_pLTServer->WriteToMessageCompPosition(hMessage, &(theStruct.vFirePos)); //g_pLTServer->WriteToMessageCompPosition(hMessage, &(theStruct.vPos)); //g_pLTServer->WriteToMessageCompPosition(hMessage, &(theStruct.vSurfaceNormal)); g_pLTServer->EndMessage2(hMessage, MESSAGE_NAGGLEFAST); }
void CreateClientWeaponFX(CLIENTWEAPONFX & theStruct) { if (!g_pLTServer) return; // make sure the impact FX in valid ASSERT( ( 0 <= theStruct.eImpactType ) || ( IMPACT_TYPE_COUNT > theStruct.eImpactType ) ); // If this is a moveable object, set the flags of fx to ignore // marks and smoke... if (IsMoveable(theStruct.hObj)) { theStruct.wIgnoreFX |= WFX_MARK; // Create a server-side mark if applicable... if (CanMarkObject(theStruct.hObj)) { AMMO const *pAmmo = g_pWeaponMgr->GetAmmo(theStruct.nAmmoId); if (pAmmo) { if (pAmmo->pImpactFX) { if (WFX_MARK & pAmmo->pImpactFX->nFlags) { CreateServerMark((CLIENTWEAPONFX)theStruct); } } // Create an exit mark if applicable... if (pAmmo->pFireFX) { if (WFX_EXITMARK & pAmmo->pFireFX->nFlags) { CreateServerExitMark((const CLIENTWEAPONFX)theStruct); } } } } } // Do impact dings if applicable... if (!(IsMultiplayerGame() && IsCharacter(theStruct.hObj))) { theStruct.wIgnoreFX |= WFX_IMPACTDING; } // [KLS 2/28/02] - If the object hit is a character, re-evaluate the surface type. // We do this here because the process of applying damage to the character may have // changed the character's surface type (e.g., from Armor to Flesh). if (IsCharacter(theStruct.hObj)) { theStruct.nSurfaceType = GetSurfaceType(theStruct.hObj); } // Tell all the clients who can see this fx about the fx... CAutoMessage cMsg; cMsg.Writeuint8(SFX_WEAPON_ID); cMsg.WriteObject(theStruct.hObj); cMsg.WriteObject(theStruct.hFiredFrom); cMsg.Writeuint8(theStruct.nWeaponId); cMsg.Writeuint8(theStruct.nAmmoId); cMsg.Writeuint8(theStruct.nSurfaceType); cMsg.Writeuint16(theStruct.wIgnoreFX); cMsg.Writeuint8(theStruct.nShooterId); cMsg.WriteLTVector(theStruct.vFirePos); cMsg.WriteLTVector(theStruct.vPos); cMsg.WriteLTVector(theStruct.vSurfaceNormal); cMsg.Writeuint8(theStruct.eImpactType); g_pLTServer->SendSFXMessage(cMsg.Read(), theStruct.vPos, 0); }
void CSpear::HandleImpact(HOBJECT hObj) { if (!g_vtSpearStickPercentage.IsInitted()) { g_vtSpearStickPercentage.Init(g_pLTServer, "SpearStickPercent", LTNULL, 0.9f); } if (!m_pAmmoData || !m_pAmmoData->pProjectileFX) { CProjectile::HandleImpact(hObj); return; } CollisionInfo info; g_pLTServer->GetLastCollision(&info); LTVector vPos, vVel, vCurVel, vP0, vP1; g_pLTServer->GetObjectPos(m_hObject, &vPos); LTRotation rRot; g_pLTServer->GetObjectRotation(m_hObject, &rRot); // Should we break the spear? enum SpearAction { eSpearActionBreak, eSpearActionStickWorld, eSpearActionStickAI, eSpearActionStickPlayer, eSpearActionStickBody }; SpearAction eSpearAction = eSpearActionBreak; // Randomly break even if we could sometimes stick... if (GetRandom(0.0, 1.0f) > g_vtSpearStickPercentage.GetFloat()) { eSpearAction = eSpearActionBreak; } else if (IsMainWorld(hObj)) { // Calculate where we really hit the world... g_pLTServer->GetVelocity(m_hObject, &vVel); vP1 = vPos; vCurVel = vVel * g_pLTServer->GetFrameTime(); vP0 = vP1 - vCurVel; vP1 += vCurVel; LTFLOAT fDot1 = VEC_DOT(info.m_Plane.m_Normal, vP0) - info.m_Plane.m_Dist; LTFLOAT fDot2 = VEC_DOT(info.m_Plane.m_Normal, vP1) - info.m_Plane.m_Dist; if (fDot1 < 0.0f && fDot2 < 0.0f || fDot1 > 0.0f && fDot2 > 0.0f) { vPos = vP1; } else { LTFLOAT fPercent = -fDot1 / (fDot2 - fDot1); VEC_LERP(vPos, vP0, vP1, fPercent); } // Set our new "real" pos... g_pLTServer->SetObjectPos(m_hObject, &vPos); eSpearAction = eSpearActionStickWorld; } else if (IsMoveable(hObj)) { if (IsAI(hObj)) { // Attach to a AI eSpearAction = eSpearActionStickAI; } else if (IsPlayer(hObj)) { // Attach to a Player eSpearAction = eSpearActionStickPlayer; } else if (IsBody(hObj)) { // Attach to a body eSpearAction = eSpearActionStickBody; } else { // Could probably come up with a way to attach to moveable // non-character objects (like doors), but it is much easier // to just break it ;)... eSpearAction = eSpearActionBreak; } } // If the surface is too hard, the spear will just break when // it hits it... SurfaceType eSurf = GetSurfaceType(info); SURFACE* pSurf = g_pSurfaceMgr->GetSurface(eSurf); if ((eSpearActionBreak == eSpearAction) || ((eSpearActionStickWorld == eSpearAction) && pSurf && pSurf->fHardness > 0.5)) { // Create spear debris... DEBRIS* pDebris = g_pDebrisMgr->GetDebris(m_pAmmoData->szName); if (pDebris) { vVel.Norm(); LTVector vNegVel = -vVel; CreatePropDebris(vPos, vNegVel, pDebris->nId); } CProjectile::HandleImpact(hObj); return; } // Create the Spear powerup... char szSpawn[512]; sprintf(szSpawn, "AmmoBox AmmoType1 %s;AmmoCount1 1;Filename %s;Skin %s", m_pAmmoData->szName, m_pAmmoData->pProjectileFX->szModel, m_pAmmoData->pProjectileFX->szSkin); LTVector vScale = m_pAmmoData->pProjectileFX->vModelScale; // Make sure the spear sticks out a little ways... vVel.Norm(); vPos -= (vVel * vScale.z/2.0f); if (eSpearActionStickWorld == eSpearAction) { g_pLTServer->AlignRotation(&rRot, &vVel, LTNULL); } BaseClass* pClass = SpawnObject(szSpawn, LTVector(-10000,-10000,-10000), rRot); if (pClass) { g_pLTServer->ScaleObject(pClass->m_hObject, &vScale); LTVector vDims; g_pLTServer->GetObjectDims(pClass->m_hObject, &vDims); vDims.x *= vScale.x; vDims.y *= vScale.y; vDims.z *= vScale.z; g_pLTServer->SetObjectDims(pClass->m_hObject, &vDims); // We don't want other projectiles to impact on us... //uint32 dwUsrFlags = g_pLTServer->GetObjectUserFlags(pClass->m_hObject); //dwUsrFlags |= USRFLG_IGNORE_PROJECTILES; //g_pLTServer->SetObjectUserFlags(pClass->m_hObject, dwUsrFlags); if ( eSpearActionStickAI == eSpearAction || eSpearActionStickPlayer == eSpearAction ) { g_pLTServer->SetObjectUserFlags(pClass->m_hObject, g_pLTServer->GetObjectUserFlags(pClass->m_hObject) & ~USRFLG_GLOW); g_pLTServer->SetObjectFlags(pClass->m_hObject, g_pLTServer->GetObjectFlags(pClass->m_hObject) & ~FLAG_TOUCH_NOTIFY); if ( eSpearActionStickPlayer == eSpearAction ) { g_pLTServer->SetObjectUserFlags(pClass->m_hObject, g_pLTServer->GetObjectUserFlags(pClass->m_hObject) | USRFLG_ATTACH_HIDE1SHOW3); } // Attach it to the character CCharacter* pCharacter = (CCharacter*)g_pLTServer->HandleToObject(hObj); pCharacter->AddSpear(pClass->m_hObject, pCharacter->GetModelNodeLastHit(), rRot); } else if ( eSpearActionStickBody == eSpearAction ) { g_pLTServer->SetObjectUserFlags(pClass->m_hObject, g_pLTServer->GetObjectUserFlags(pClass->m_hObject) & ~USRFLG_GLOW); g_pLTServer->SetObjectFlags(pClass->m_hObject, g_pLTServer->GetObjectFlags(pClass->m_hObject) & ~FLAG_TOUCH_NOTIFY); // Attach it to the body Body* pBody = (Body*)g_pLTServer->HandleToObject(hObj); pBody->AddSpear(pClass->m_hObject, rRot); } else // ( eSpearActionStickWorld == eSpearAction ) { // Move it to the right position in the world g_pLTServer->SetObjectPos(pClass->m_hObject, &vPos); } } CProjectile::HandleImpact(hObj); }