//----------------------------------------------------------------------------- // Purpose: // Input : pView - // pt - Point in client coordinates. // bValidOnly - // Output : //----------------------------------------------------------------------------- int Box3D::HitTest(CMapView *pView, const Vector2D &ptClient, bool bTestHandles) { bool bHit = false; if ( pView->HitTest( ptClient, bmins, bmaxs ) ) { // The point is inside the main rect. m_LastHitTestHandle.Init(); bHit = true; } if ( !m_bEnableHandles || !bTestHandles ) { // Handles are turned off, so we don't need to do any more testing. // Return whether we hit the main rect or not. return bHit; } // check if we hit a handle Vector handles[3*3*3]; int numHandles = GetVisibleHandles( handles, pView, m_TranslateMode ); Vector vOffset(HANDLE_OFFSET,HANDLE_OFFSET,HANDLE_OFFSET); if ( pView->IsOrthographic() ) { vOffset /= pView->GetCamera()->GetZoom(); } else { vOffset.Init(); } Vector vCenter = (bmins+bmaxs)/2; Vector vDelta = (bmaxs + vOffset) - vCenter; for ( int i = 0; i<numHandles; i++ ) { Vector pos = vCenter + vDelta * handles[i]; if ( HitRect( pView, ptClient, pos, HANDLE_RADIUS ) ) { // remember handle found m_LastHitTestHandle = handles[i]; bHit = true; break; } } return bHit; }
void SecurityCamera::CreateLight() { // Create the light...and attach it to the camera... ObjectCreateStruct theStruct; INIT_OBJECTCREATESTRUCT(theStruct); theStruct.m_Pos = m_vPos; g_pServerButeMgr->GetSecurityCameraString(SCS_GREEN_LIGHT, theStruct.m_Filename, ARRAY_LEN(theStruct.m_Filename)); theStruct.m_Flags = FLAG_VISIBLE; // | FLAG_GLOWSPRITE; theStruct.m_Flags2 = FLAG2_ADDITIVE; theStruct.m_ObjectType = OT_SPRITE; HCLASS hClass = g_pLTServer->GetClass("BaseClass"); LPBASECLASS pSprite = g_pLTServer->CreateObject(hClass, &theStruct); if (!pSprite) return; m_hLight = pSprite->m_hObject; // Don't eat ticks please... ::SetNextUpdate(m_hLight, UPDATE_NEVER); m_eLightColor = eGreen; LTVector vScale(1, 1, 1); vScale.x = g_pServerButeMgr->GetSecurityCameraFloat("LightScale"); vScale.y = vScale.x; g_pLTServer->ScaleObject(m_hLight, &vScale); // Attach the sprite to the the camera... LTVector vOffset(0, 0, 0); LTRotation rOffset; HATTACHMENT hAttachment; LTRESULT dRes = g_pLTServer->CreateAttachment(m_hObject, m_hLight, "Light", &vOffset, &rOffset, &hAttachment); if (dRes != LT_OK) { g_pLTServer->RemoveObject(m_hLight); m_hLight = LTNULL; return; } }
void LayerNode::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); ISceneNode* cameraNode = SceneManager->getActiveCamera(); core::matrix4 mxTrans = cameraNode->getAbsoluteTransformation(); core::vector3df vCamPos = cameraNode->getPosition(); core::vector3df vCamScale = cameraNode->getScale(); core::vector3df vCamRot = cameraNode->getRotation(); //Zoom factor: for Factor=0, zoom = 1; for Factor=1, zoom = vCamScale; vCamScale.X = 1 - ( (1 - vCamScale.X) * m_paraxZoomFactor ); vCamScale.Y = 1 - ( (1 - vCamScale.Y) * m_paraxZoomFactor ); core::vector3df vCamPos2 = cameraNode->getPosition(); // Apply Offset core::vector3df vOffset(m_offsetX, m_offsetY, 0); // Apply parallax factor vCamPos2.X *= m_paraxFactorX; vCamPos2.Y *= m_paraxFactorY; mxTrans = core::matrix4().setTranslation(vCamPos)* core::matrix4().setScale(vCamScale)* core::matrix4().setTranslation(-vCamPos)* core::matrix4().setRotationDegrees(vCamRot)* core::matrix4().setTranslation(-vCamPos)* // remove camera offset because is applied automatically later by Irrlicht core::matrix4().setTranslation(vOffset)* // apply offset without parallax factor to make easy to adjust layer core::matrix4().setTranslation(vCamPos2) // then apply modified by parallax factor camera position ; driver->setMaterial(Material); driver->setTransform(video::ETS_WORLD, mxTrans*AbsoluteTransformation); Drawing::draw2DImage( driver, m_texture, core::recti( 0, 0, m_width, m_height), core::IdentityMatrix, true, video::SColor(255, 255, 255, 255)); }
void CUIHUD3D::UpdateView(const SViewParams &viewParams) { CActor* pLocalPlayer = (CActor*)g_pGame->GetIGameFramework()->GetClientActor(); if (gEnv->IsEditor() && !gEnv->IsEditing() && !m_pHUDRootEntity) SpawnHudEntities(); if (m_pHUDRootEntity && pLocalPlayer) { Vec3 position = viewParams.position; const Vec3 viewDir = viewParams.rotation.GetColumn1(); Vec3 vOffset(0,0,0); if (!pLocalPlayer->IsDead() && pLocalPlayer->GetLinkedVehicle() == NULL) { const Vec3 eyePos = pLocalPlayer->GetLocalEyePos2(); const Vec3 cameraXAxis = viewParams.rotation.GetColumn0(); const float difZ = (eyePos.z - 1.68f) * 0.4f; const float difX = (eyePos.x - 0.12f) * 0.15f; vOffset += cameraXAxis * difX; vOffset += Vec3(0, 0, difZ); } const float distance = g_pGameCVars->g_hud3D_cameraOverride ? g_pGameCVars->g_hud3d_cameraDistance : m_fHudDist; const float offset = g_pGameCVars->g_hud3D_cameraOverride ? g_pGameCVars->g_hud3d_cameraOffsetZ : m_fHudZOffset; vOffset += Vec3(0, 0, offset); position += vOffset; position += viewDir * distance; static const Quat rot90Deg = Quat::CreateRotationXYZ( Ang3(gf_PI * 0.5f, 0, 0) ); const Quat rotation = viewParams.rotation * rot90Deg; // rotate 90 degrees around X-Axis m_pHUDRootEntity->SetPos(position); m_pHUDRootEntity->SetRotation(rotation); } }
void C_ASW_Shaman::UpdateEffects() { if ( !m_hHealingTarget.Get() || GetHealth() <= 0 ) { if ( m_pHealEffect ) { m_pHealEffect->StopEmission(); m_pHealEffect = NULL; } return; } if ( m_pHealEffect ) { if ( m_pHealEffect->GetControlPointEntity( 1 ) != m_hHealingTarget.Get() ) { m_pHealEffect->StopEmission(); m_pHealEffect = NULL; } } if ( !m_pHealEffect ) { m_pHealEffect = ParticleProp()->Create( "shaman_heal_attach", PATTACH_POINT_FOLLOW, "nozzle" ); // "heal_receiver" } Assert( m_pHealEffect ); if ( m_pHealEffect->GetControlPointEntity( 1 ) == NULL ) { C_BaseEntity *pTarget = m_hHealingTarget.Get(); Vector vOffset( 0.0f, 0.0f, pTarget->WorldSpaceCenter().z - pTarget->GetAbsOrigin().z ); ParticleProp()->AddControlPoint( m_pHealEffect, 1, pTarget, PATTACH_ABSORIGIN_FOLLOW, NULL, vOffset ); m_pHealEffect->SetControlPointOrientation( 0, pTarget->Forward(), -pTarget->Left(), pTarget->Up() ); } }
void Body::Update() { if ( !m_hObject ) return; LTVector vPos, vMin, vMax; g_pLTServer->GetWorldBox(vMin, vMax); g_pLTServer->GetObjectPos(m_hObject, &vPos); if (vPos.x < vMin.x || vPos.y < vMin.y || vPos.z < vMin.z || vPos.x > vMax.x || vPos.y > vMax.y || vPos.z > vMax.z) { RemoveObject(); } // Update the animator m_Animator.Update(); // Make sure our hit box is in the correct position... UpdateHitBox(); if ( m_bFirstUpdate ) { m_bFirstUpdate = LTFALSE; m_fStartTime = g_pLTServer->GetTime(); } SetNextUpdate(s_fUpdateDelta); // We keep the body active to update dims for 2.0 seconds LTBOOL bUpdatingDims = g_pLTServer->GetTime() < m_fStartTime + 2.0f; // The deactivate-check, update, activate-check is ordered so that // deactivation will always happen one update after you enter a state, // but activation will always happen when you just entered the state. // This avoids a lot of issues with changing between active/inactive states. if ( !bUpdatingDims && (!m_pState || m_pState->CanDeactivate()) ) { // Finalize the dims of our hit box... if (m_hHitBox) { CCharacterHitBox* pHitBox = (CCharacterHitBox*) g_pLTServer->HandleToObject(m_hHitBox); if ( pHitBox ) { // For now just make the hit box 50% larger than our dims... LTVector vDims, vNewDims; g_pLTServer->GetObjectDims(m_hHitBox, &vDims); vNewDims = vDims; vNewDims.x *= 3.0f; vNewDims.z *= 3.0f; // Update 1.003, some cases the dims can get weird, not // sure why...Just make sure they are reasonable... if (vNewDims.x <= 0.0f || vNewDims.x > 75.0f) { vNewDims.x = 75.0f; } if (vNewDims.z <= 0.0f || vNewDims.z > 75.0f) { vNewDims.z = 75.0f; } // Only shrink us down if we're not sitting or stuck to a wall if ( m_eBodyStatePrevious == eBodyStateChair ) { } else if ( m_eBodyStatePrevious == eBodyStateArrow ) { } else { vNewDims.y = 15.0f; } g_pLTServer->SetObjectDims(m_hHitBox, &vNewDims); LTVector vOffset(0, vNewDims.y - vDims.y, 0); pHitBox->SetOffset(vOffset); pHitBox->Update(); } } SetNextUpdate(0.0f); } if ( m_pState ) { m_pState->Update(); } if ( bUpdatingDims || (m_pState && !m_pState->CanDeactivate()) ) { SetNextUpdate(s_fUpdateDelta); } }
//------------------------------------------------------------------------ tSoundID CItem::PlayAction(const ItemString &actionName, int layer, bool loop, uint32 flags, float speedOverride) { if(!m_enableAnimations || !IsOwnerInGame()) return (tSoundID)-1; TActionMap::iterator it = m_sharedparams->actions.find(CONST_TEMPITEM_STRING(actionName)); if(it == m_sharedparams->actions.end()) { // GameWarning("Action '%s' not found on item '%s'!", actionName, GetEntity()->GetName()); for(int i=0; i<eIGS_Last; i++) { m_animationTime[i]=0; m_animationSpeed[i]=1.0f; m_animationEnd[i]=0; } return 0; } bool fp = m_stats.fp; if(m_parentId) { CItem *pParent=static_cast<CItem *>(m_pItemSystem->GetItem(m_parentId)); if(pParent) fp=pParent->GetStats().fp; } if(flags&eIPAF_ForceFirstPerson) fp = true; if(flags&eIPAF_ForceThirdPerson) fp = false; int sid=fp?eIGS_FirstPerson:eIGS_ThirdPerson; SAction &action = it->second; tSoundID result = INVALID_SOUNDID; if((flags&eIPAF_Sound) && !action.sound[sid].name.empty() && IsSoundEnabled() && g_pGameCVars->i_soundeffects) { int nSoundFlags = FLAG_SOUND_DEFAULT_3D; nSoundFlags |= flags&eIPAF_SoundStartPaused?FLAG_SOUND_START_PAUSED:0; IEntitySoundProxy *pSoundProxy = GetSoundProxy(true); //GetSound proxy from dualwield master if neccesary if(IsDualWieldSlave()) { CItem *pMaster = static_cast<CItem *>(GetDualWieldMaster()); if(pMaster) { pSoundProxy = pMaster->GetSoundProxy(true); } } EntityId pSkipEnts[3]; int nSkipEnts = 0; // TODO for Marcio :) // check code changes // Skip the Item pSkipEnts[nSkipEnts] = GetEntity()->GetId(); ++nSkipEnts; // Skip the Owner if(GetOwner()) { pSkipEnts[nSkipEnts] = GetOwner()->GetId(); ++nSkipEnts; } if(pSoundProxy) { TempResourceName name; FixResourceName(action.sound[sid].name, name, flags); //nSoundFlags = nSoundFlags | (fp?FLAG_SOUND_DEFAULT_3D|FLAG_SOUND_RELATIVE:FLAG_SOUND_DEFAULT_3D); Vec3 vOffset(0,0,0); if(fp) vOffset.x = 0.3f; // offset for first person weapon to the front if(!g_pGameCVars->i_staticfiresounds) { result = pSoundProxy->PlaySoundEx(name, vOffset, FORWARD_DIRECTION, nSoundFlags, 1.0f, 0, 0, eSoundSemantic_Weapon, pSkipEnts, nSkipEnts); ISound *pSound = pSoundProxy->GetSound(result); if(pSound && action.sound[sid].sphere>0.0f) pSound->SetSphereSpec(action.sound[sid].sphere); } else { SInstanceAudio *pInstanceAudio=0; if(action.sound[sid].isstatic) { TInstanceActionMap::iterator iit = m_instanceActions.find(CONST_TEMPITEM_STRING(actionName)); if(iit == m_instanceActions.end()) { std::pair<TInstanceActionMap::iterator, bool> insertion=m_instanceActions.insert(TInstanceActionMap::value_type(actionName, SInstanceAction())); pInstanceAudio=&insertion.first->second.sound[sid]; } else pInstanceAudio=&iit->second.sound[sid]; } if(pInstanceAudio && (pInstanceAudio->id != INVALID_SOUNDID) && (name != pInstanceAudio->static_name)) ReleaseStaticSound(pInstanceAudio); if(!pInstanceAudio || pInstanceAudio->id == INVALID_SOUNDID) { result = pSoundProxy->PlaySoundEx(name, vOffset, FORWARD_DIRECTION, nSoundFlags, 1.0f, 0, 0, eSoundSemantic_Weapon, pSkipEnts, nSkipEnts); ISound *pSound = pSoundProxy->GetSound(result); if(pSound && action.sound[sid].sphere>0.0f) pSound->SetSphereSpec(action.sound[sid].sphere); } if(action.sound[sid].isstatic) { if(pInstanceAudio->id == INVALID_SOUNDID) { if(pSoundProxy->SetStaticSound(result, true)) { pInstanceAudio->id = result; pInstanceAudio->static_name = name; pInstanceAudio->synch = action.sound[sid].issynched; } } else { ISound *pSound = pSoundProxy->GetSound(pInstanceAudio->id); if(pSound) pSound->Play(1.0, true, true, pSoundProxy); } } } if(gEnv->pAISystem && action.sound[sid].airadius > 0.0f) { EntityId ownerId = GetOwner() ? GetOwner()->GetId() : 0; // associate sound event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) if(CActor *pOwnerActor = GetOwnerActor()) { IVehicle *pOwnerVehicle = pOwnerActor->GetLinkedVehicle(); if(pOwnerVehicle && pOwnerVehicle->GetEntityId()) ownerId = pOwnerVehicle->GetEntityId(); } SAIStimulus stim(AISTIM_SOUND, AISOUND_WEAPON, ownerId?ownerId:GetEntityId() , 0, GetEntity()->GetWorldPos(), ZERO, action.sound[sid].airadius); gEnv->pAISystem->RegisterStimulus(stim); } } } if(flags&eIPAF_Animation) { TempResourceName name; // generate random number only once per call to allow animations to // match across geometry slots (like first person and third person) float randomNumber = Random(); for(int i=0; i<eIGS_Last; i++) { if(!(flags&(1<<i))) continue; int nanimations=action.animation[i].size(); if(nanimations <= 0) continue; int anim = int(randomNumber * float(nanimations)); if(action.animation[i][anim].name.empty()) continue; FixResourceName(action.animation[i][anim].name, name, flags); if((i == eIGS_Owner) || (i == eIGS_OwnerLooped)) { if(!action.animation[i][anim].name.empty()) { bool looping=(eIGS_OwnerLooped==i); CActor *pOwner = GetOwnerActor(); if(pOwner) { if(IsDualWield() && !m_sharedparams->params.dual_wield_pose.empty()) pOwner->PlayAction(name, m_sharedparams->params.dual_wield_pose.c_str(), looping); else pOwner->PlayAction(name, m_sharedparams->params.pose.c_str(), looping); } } continue; } else if(i == eIGS_OffHand) { if(!action.animation[eIGS_OffHand][anim].name.empty()) { CActor *pOwner = GetOwnerActor(); if(pOwner) { CItem *pOffHand = pOwner->GetItemByClass(CItem::sOffHandClass); if(pOffHand && pOffHand!=this) { uint32 ohflags=eIPAF_Default; if(action.animation[eIGS_OffHand][anim].blend==0.0f) ohflags|=eIPAF_NoBlend; pOffHand->PlayAction(action.animation[eIGS_OffHand][anim].name, 0, false, ohflags); } } } continue; } SAnimation &animation=action.animation[i][anim]; if(!animation.name.empty()) { float blend = animation.blend; if(flags&eIPAF_NoBlend) blend = 0.0f; if(speedOverride > 0.0f) PlayAnimationEx(name, i, layer, loop, blend, speedOverride, flags); else PlayAnimationEx(name, i, layer, loop, blend, animation.speed, flags); } if((m_stats.fp || m_stats.viewmode&eIVM_FirstPerson) && i==eIGS_FirstPerson && !animation.camera_helper.empty()) { m_camerastats.animating=true; m_camerastats.helper=animation.camera_helper; m_camerastats.position=animation.camera_pos; m_camerastats.rotation=animation.camera_rot; m_camerastats.follow=animation.camera_follow; m_camerastats.reorient=animation.camera_reorient; } else if(m_camerastats.animating) m_camerastats=SCameraAnimationStats(); } } if(flags&eIPAF_Effect && !action.effect[sid].name.empty()) { // change this to attach, if needed SpawnEffect(sid, action.effect[sid].name.c_str(), action.effect[sid].helper.c_str()); } if(action.children) { for(TAccessoryMap::iterator ait=m_accessories.begin(); ait!=m_accessories.end(); ait++) { EntityId aId=(EntityId)ait->second; CItem *pAccessory=static_cast<CItem *>(m_pItemSystem->GetItem(aId)); if(pAccessory) pAccessory->PlayAction(actionName, layer, loop, flags, speedOverride); } } return result; }
void UpdateVPhysicsObjects() { int nPhysicsObjectInterval = sv_benchmark_numticks.GetInt() / s_nBenchmarkPhysicsObjects; int nNextSpawnTick = m_nLastPhysicsObjectTick + nPhysicsObjectInterval; if ( GetTickOffset() >= nNextSpawnTick ) { m_nLastPhysicsObjectTick = nNextSpawnTick; if ( m_PhysicsObjects.Count() < s_nBenchmarkPhysicsObjects ) { // Find a bot to spawn it from. CUtlVector<CBasePlayer*> curPlayers; for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); if ( pPlayer && (pPlayer->GetFlags() & FL_FAKECLIENT) ) { curPlayers.AddToTail( pPlayer ); } } if ( curPlayers.Count() > 0 && m_PhysicsModelNames.Count() > 0 ) { int iModelName = this->RandomInt( 0, m_PhysicsModelNames.Count() - 1 ); const char *pModelName = m_PhysicsModelNames[iModelName]; int iPlayer = this->RandomInt( 0, curPlayers.Count() - 1 ); Vector vSpawnPos = curPlayers[iPlayer]->EyePosition() + Vector( 0, 0, 50 ); // We'll try 15 locations around the player to spawn this thing. for ( int i=0; i < 15; i++ ) { Vector vOffset( this->RandomFloat( -2000, 2000 ), this->RandomFloat( -2000, 2000 ), 0 ); CPhysicsProp *pProp = CreatePhysicsProp( pModelName, vSpawnPos, vSpawnPos+vOffset, curPlayers[iPlayer], false, "prop_physics_multiplayer" ); if ( pProp ) { m_PhysicsObjects.AddToTail( pProp ); pProp->SetAbsVelocity( Vector( this->RandomFloat(-500,500), this->RandomFloat(-500,500), this->RandomFloat(-500,500) ) ); break; } } } } } // Give them all a boost periodically. int nPhysicsForceInterval = sv_benchmark_numticks.GetInt() / 20; int nNextForceTick = m_nLastPhysicsForceTick + nPhysicsForceInterval; if ( GetTickOffset() >= nNextForceTick ) { m_nLastPhysicsForceTick = nNextForceTick; for ( int i=0; i < m_PhysicsObjects.Count(); i++ ) { CBaseEntity *pEnt = m_PhysicsObjects[i]; if ( pEnt ) { IPhysicsObject *pPhysicsObject = pEnt->VPhysicsGetObject(); if ( pPhysicsObject ) { float flAngImpulse = 300000; float flForce = 500000; AngularImpulse vAngularImpulse( this->RandomFloat(-flAngImpulse,flAngImpulse), this->RandomFloat(-flAngImpulse,flAngImpulse), this->RandomFloat(flAngImpulse,flAngImpulse) ); pPhysicsObject->ApplyForceCenter( Vector( this->RandomFloat(-flForce,flForce), this->RandomFloat(-flForce,flForce), this->RandomFloat(0,flForce) ) ); } } } } }
// ----------------------------------------------------------------------- // // // ROUTINE: CAutoTargetMgr::GenerateCharArray() // // PURPOSE: Fill array with list of chars sorted by distance // // ----------------------------------------------------------------------- // void CAutoTargetMgr::GenerateCharArray() { //clear our target array m_Targets.resize(0); CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr(); //step through the chars CSpecialFXList* const pCharList = psfxMgr->GetFXList(SFX_CHARACTER_ID); int nNumSFX = pCharList->GetSize(); for (int nChar=0; nChar < nNumSFX; nChar++) { CCharacterFX* pChar = (CCharacterFX*)(*pCharList)[nChar]; if (pChar) { if (pChar->m_cs.bIsPlayer) { //filter out local player HLOCALOBJ hPlayerObj = g_pLTClient->GetClientObject(); if (hPlayerObj == pChar->GetServerObj()) continue; if(pChar->IsPlayerDead()) continue; //if this is a team game filter out our teammates if (GameModeMgr::Instance( ).m_grbUseTeams ) { // Get the client information of the body and us. uint32 nId = pChar->m_cs.nClientID; CClientInfoMgr* pCIMgr = g_pInterfaceMgr->GetClientInfoMgr(); CLIENT_INFO* pCI = pCIMgr->GetClientByID(nId); CLIENT_INFO *pLocalCI = g_pInterfaceMgr->GetClientInfoMgr()->GetLocalClient(); // Only allow us to auto-target people on the other team. if( pCI && pLocalCI ) { if (pCI->nTeamID == pLocalCI->nTeamID) continue; } } } else { // Check alignment of non-players if(pChar->m_cs.eCrosshairPlayerStance != kCharStance_Hate) continue; } //filter out anyone outside the cone LTVector vTargetPos; g_pLTClient->GetObjectPos(pChar->GetServerObj(), &vTargetPos); LTVector vOffset(0.0f,32.0f,0.0f); // we check both upper and lower parts of the body and if either is in the cone, we're good if (IsPointInCone( vTargetPos - vOffset) || IsPointInCone( vTargetPos + vOffset) ) { // we only care about the n closest characters, so... // if the new one farther away than the n-th one, drop it, // otherwise drop the n-th one and insert the new one //step through the chars we already know about... CharFXArray::iterator iter = m_Targets.begin(); bool bInserted = false; while (iter != m_Targets.end() && !bInserted) { //figure out how far away this one is CCharacterFX* pTestChar = (CCharacterFX*)(*iter); LTVector vTestPos; g_pLTClient->GetObjectPos(pTestChar->GetServerObj(), &vTestPos); float fTestDistSqr = m_vFirePos.DistSqr(vTestPos); //if this char is farther away than the one we're inserting if (fTestDistSqr > m_fRangeSqr) { //if our list is full, pop off the last one... if (m_Targets.size() >= MAX_AUTOTARGET_CHARACTERS) m_Targets.pop_back(); m_Targets.insert(iter,pChar); bInserted = true; } iter++; } //if we haven't inseted it yet, and we have room, add it to the back if (!bInserted && m_Targets.size() < MAX_AUTOTARGET_CHARACTERS) m_Targets.push_back(pChar); } } } }
void CHUDDebugInput::Send() { char szPath[MAX_PATH*2]; char szTemp[MAX_PATH]; char szShotname[MAX_PATH + 1]; LTFileOperations::GetUserDirectory(szPath, LTARRAYSIZE(szPath)); LTStrCat(szPath,"DebugLog",LTARRAYSIZE(szPath)); LTStrCat(szPath,FILE_PATH_SEPARATOR,LTARRAYSIZE(szPath)); LTStrCpy(szTemp,g_pMissionMgr->GetCurrentWorldName(),LTARRAYSIZE(szTemp)); char* szWorld = strrchr(szTemp,FILE_PATH_SEPARATOR[0]); if (szWorld) { szWorld++; } else { szWorld = szTemp; } LTStrCat(szPath,szWorld,LTARRAYSIZE(szPath)); if (!CWinUtil::DirExist(szPath)) { CWinUtil::CreateDir(szPath); } LTStrCat(szPath,FILE_PATH_SEPARATOR,LTARRAYSIZE(szPath)); //determine a filename for this. This should start with the screenshot console variable and be //numbered sequentially //an upper cap to make sure that we don't attempt to create screenshots indefinitely, which could //potentially be caused by some file access issues static const uint32 knMaxScreenshotAttempts = 1000; for(uint32 nCurrScreenshotIndex = 0; nCurrScreenshotIndex < knMaxScreenshotAttempts; nCurrScreenshotIndex++) { //build up the filename to use for this screenshot LTSNPrintF(szShotname, LTARRAYSIZE(szShotname), "Screenshot%03d.jpg", nCurrScreenshotIndex); char pszFilename[MAX_PATH]; LTSNPrintF(pszFilename, LTARRAYSIZE(pszFilename), "DebugLog%s%s%s%s", FILE_PATH_SEPARATOR,szWorld,FILE_PATH_SEPARATOR,szShotname); // get the user path to the screenshot file, as we need this to check if the file exists. char pszUserFilename[MAX_PATH]; g_pLTClient->FileMgr()->GetAbsoluteUserFileName( pszFilename, pszUserFilename, LTARRAYSIZE( pszUserFilename ) ); //see if this file already exists - if it does, continue searching for an unused file if ( !LTFileOperations::FileExists( pszUserFilename ) ) { //the filename doesn't exist, so go ahead and try to make the screenshot if(g_pLTClient->GetRenderer()->MakeScreenShot(pszUserFilename) == LT_OK) { g_pLTClient->CPrint("Successfully created screenshot %s", pszUserFilename); } else { g_pLTClient->CPrint("Failed to create screenshot %s", pszUserFilename); } break; } } //report overflow if(nCurrScreenshotIndex >= knMaxScreenshotAttempts) { g_pLTClient->CPrint("Unable to create screenshot. Please make sure that the directory is readable and that there are less than %d screenshots", knMaxScreenshotAttempts); } Show(false); // Ignore empty messages. if( !m_szDebugStr[0] ) return; char szMsg[256]; static bool bUseTime = false; if (bUseTime) { time_t tmSys; time( &tmSys ); struct tm* pTimeDate = NULL; pTimeDate = localtime (&tmSys); if (pTimeDate) { LTSNPrintF(szMsg, LTARRAYSIZE( szMsg ), "<tr><td>%02d/%02d/%02d %02d:%02d:%02d</td>", pTimeDate->tm_mon + 1, pTimeDate->tm_mday, (pTimeDate->tm_year + 1900) % 100, pTimeDate->tm_hour, pTimeDate->tm_min, pTimeDate->tm_sec); } } else { LTSNPrintF(szMsg, LTARRAYSIZE( szMsg ), "<tr>"); } //determine the offset we should use on the positions LTVector vOffset(0, 0, 0); g_pLTClient->GetSourceWorldOffset(vOffset); HLOCALOBJ hPlayerObj = g_pLTClient->GetClientObject(); if (hPlayerObj) { char buf[256]; LTVector vPos; g_pLTClient->GetObjectPos(hPlayerObj, &vPos); //handle the shift from the current world to the source world vPos += vOffset; LTSNPrintF(buf, LTARRAYSIZE(buf), "<td>(pos %0.0f %0.0f %0.0f)</td>", vPos.x, vPos.y, vPos.z); LTStrCat(szMsg,buf,LTARRAYSIZE(szMsg)); } LTSNPrintF(szTemp,LTARRAYSIZE(szTemp),"<td><a href=\"%s\">%s</a></td>",szShotname,MPW2A(m_szDebugStr).c_str()); LTStrCat(szMsg,szTemp,LTARRAYSIZE(szMsg)); LTStrCat(szMsg,"</tr>\r\n",LTARRAYSIZE(szMsg)); CLTFileWrite cFileWrite; LTStrCat( szPath, "debuglog.htm", LTARRAYSIZE( szPath )); bool bNewFile = !CWinUtil::FileExist(szPath); if (cFileWrite.Open(szPath,true)) { if (bNewFile) { char szTmp[128] = "<HTML><BODY>\r\n<table>\r\n"; cFileWrite.Write(szTmp,LTStrLen(szTmp)); } cFileWrite.Write(szMsg,LTStrLen(szMsg)); cFileWrite.Close(); } }
void SecurityCamera::SetupDisabledState() { if (m_eState == eStateDisabled || m_hDisablerModel) return; g_pCommonLT->SetObjectFlags(m_hObject, OFT_User, 0, USRFLG_GADGET_CAMERA_DISABLER); // Create the camera disabler model, and attach it to the camera... ObjectCreateStruct theStruct; INIT_OBJECTCREATESTRUCT(theStruct); theStruct.m_Pos = m_vPos; char szFile[128] = {0}; g_pServerButeMgr->GetSecurityCameraString( SCS_DISABLER_FILENAME, szFile, ARRAY_LEN( szFile )); if( szFile[0] ) SAFE_STRCPY(theStruct.m_Filename, szFile); szFile[0] = '\0'; g_pServerButeMgr->GetSecurityCameraString( SCS_DISABLER_SKIN, szFile, ARRAY_LEN( szFile )); if( szFile[0] ) SAFE_STRCPY(theStruct.m_SkinName, szFile); theStruct.m_Flags = FLAG_VISIBLE | FLAG_GOTHRUWORLD; theStruct.m_ObjectType = OT_MODEL; HCLASS hClass = g_pLTServer->GetClass("BaseClass"); LPBASECLASS pModel = g_pLTServer->CreateObject(hClass, &theStruct); if (!pModel) return; m_hDisablerModel = pModel->m_hObject; // Don't eat ticks please... ::SetNextUpdate(m_hDisablerModel, UPDATE_NEVER); // Attach the model to the the camera... LTVector vOffset(0, 0, 0); LTRotation rOffset; HATTACHMENT hAttachment; LTRESULT dRes = g_pLTServer->CreateAttachment(m_hObject, m_hDisablerModel, "Disabler", &vOffset, &rOffset, &hAttachment); if (dRes != LT_OK) { g_pLTServer->RemoveObject(m_hDisablerModel); m_hDisablerModel = LTNULL; return; } // Set the Disabler's animation... HMODELANIM hAni = g_pLTServer->GetAnimIndex(m_hDisablerModel, "Activate"); if (hAni) { g_pLTServer->SetModelLooping(m_hDisablerModel, LTFALSE); g_pLTServer->SetModelAnimation(m_hDisablerModel, hAni); } // Play the activate sound... szFile[0] = '\0'; g_pServerButeMgr->GetSecurityCameraString( SCS_DISABLER_SOUND, szFile, ARRAY_LEN( szFile )); LTFLOAT fRadius = g_pServerButeMgr->GetSecurityCameraFloat( SCS_SOUND_RADIUS ); if( szFile ) g_pServerSoundMgr->PlaySoundFromPos(m_vPos, szFile, fRadius, SOUNDPRIORITY_MISC_LOW); // Camera is now disabled... m_bDisabled = LTTRUE; }
LTBOOL CFireFX::CreateObject(ILTClient* pClientDE) { if (!CSpecialFX::CreateObject(pClientDE) || !g_pGameClientShell) return LTFALSE; CSFXMgr* psfxMgr = g_pGameClientShell->GetSFXMgr(); if (!psfxMgr) return LTFALSE; LTVector vZero(0, 0, 0), vOffset(0, 0, 0); CString str; uint32 dwFlags; // Get our initial pos... if (m_cs.vPos.Equals(vZero) && m_hServerObject) { g_pLTClient->GetObjectPos(m_hServerObject, &(m_cs.vPos)); } SMCREATESTRUCT sm; sm.hServerObj = m_hServerObject; sm.bRelToCameraPos = LTTRUE; sm.fInnerCamRadius = FFX_INNER_CAM_RADIUS; sm.fOuterCamRadius = FFX_INNER_CAM_RADIUS + (FFX_CAM_FALLOFF_RANGE * m_fSizeAdjust); // Create the smoke particles... if (m_cs.bCreateSmoke) { vOffset.Init(0, 20.0f * m_fSizeAdjust, 0); vOffset.y = vOffset.y > 50.0f ? 50.0f : vOffset.y; sm.vColor1.Init(100.0f, 100.0f, 100.0f); sm.vColor2.Init(150.0f, 150.0f, 150.0f); sm.vMinDriftVel.Init(-2.0f, 15.0f, -2.0f); sm.vMaxDriftVel.Init(2.0f, 50.0f, 2.0f); sm.fVolumeRadius = 5.0f * (1.5f * m_fSizeAdjust); sm.fLifeTime = 100000.0f; sm.fRadius = FFX_DEFAULT_SMOKE_PARTICLE_RADIUS * m_fSizeAdjust; sm.fParticleCreateDelta = 0.25f; sm.fMinParticleLife = 2.0f * m_fSizeAdjust; sm.fMaxParticleLife = 4.0f * m_fSizeAdjust; sm.nNumParticles = 2; //sm.bMultiply = m_cs.bBlackSmoke; sm.bIgnoreWind = LTFALSE; sm.vPos = m_cs.vPos + vOffset; sm.bAdjustParticleScale = LTTRUE; sm.fStartParticleScale = 1.0f; sm.fEndParticleScale = 0.5f; sm.bAdjustParticleAlpha = LTTRUE; sm.fStartParticleAlpha = 1.0f; sm.fEndParticleAlpha = 0.0f; sm.fMinParticleLife = sm.fMinParticleLife < FFX_MIN_SMOKE_PARTICLE_LIFETIME ? FFX_MIN_SMOKE_PARTICLE_LIFETIME : (sm.fMinParticleLife > FFX_MAX_SMOKE_PARTICLE_LIFETIME ? FFX_MAX_SMOKE_PARTICLE_LIFETIME : sm.fMinParticleLife); sm.fMaxParticleLife = sm.fMaxParticleLife > FFX_MAX_SMOKE_PARTICLE_LIFETIME ? FFX_MAX_SMOKE_PARTICLE_LIFETIME : (sm.fMaxParticleLife < FFX_MIN_SMOKE_PARTICLE_LIFETIME ? FFX_MIN_SMOKE_PARTICLE_LIFETIME : sm.fMaxParticleLife); sm.fRadius = sm.fRadius > FFX_MAX_SMOKE_PARTICLE_RADIUS ? FFX_MAX_SMOKE_PARTICLE_RADIUS : sm.fRadius; str = g_pClientButeMgr->GetSpecialFXAttributeString("FireSmokeTex"); if (str.IsEmpty()) return LTFALSE; sm.hstrTexture = g_pLTClient->CreateString((char *)(LPCSTR)str); if (!m_Smoke1.Init(&sm) || !m_Smoke1.CreateObject(m_pClientDE)) { return LTFALSE; } g_pLTClient->FreeString(sm.hstrTexture); dwFlags = g_pLTClient->GetObjectFlags(m_Smoke1.GetObject()); g_pLTClient->SetObjectFlags(m_Smoke1.GetObject(), dwFlags | FLAG_NOGLOBALLIGHTSCALE); m_Smoke1.Update(); } // Create the fire particles... if (!m_cs.bSmokeOnly) { LTFLOAT fVolumeAdjust = m_fSizeAdjust < 1.0 ? m_fSizeAdjust / 1.5f : m_fSizeAdjust * 1.5f; sm.vColor1.Init(100.0f, 100.0f, 100.0f); sm.vColor2.Init(150.0f, 150.0f, 150.0f); sm.vMinDriftVel.Init(-2.0f, 8.0f, -2.0f); sm.vMaxDriftVel.Init(2.0f, 15.0f, 2.0f); sm.fVolumeRadius = 10.0f * fVolumeAdjust; sm.fLifeTime = 100000.0f; sm.fRadius = FFX_DEFAULT_FIRE_PARTICLE_RADIUS * m_fSizeAdjust; sm.fParticleCreateDelta = 0.1f; sm.fMinParticleLife = 1.0f * m_fSizeAdjust; sm.fMaxParticleLife = 2.0f * m_fSizeAdjust; sm.nNumParticles = 3; sm.bAdditive = LTTRUE; sm.vPos = m_cs.vPos; //sm.fStartParticleScale = 1.0f; //sm.fEndParticleScale = 0.0f; sm.fMinParticleLife = sm.fMinParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME : (sm.fMinParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME : sm.fMinParticleLife); sm.fMaxParticleLife = sm.fMaxParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME : (sm.fMaxParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME : sm.fMaxParticleLife); sm.fRadius = sm.fRadius > FFX_MAX_FIRE_PARTICLE_RADIUS ? FFX_MAX_FIRE_PARTICLE_RADIUS : sm.fRadius; str = g_pClientButeMgr->GetSpecialFXAttributeString("FireTex"); if (str.IsEmpty()) return LTFALSE; sm.hstrTexture = g_pLTClient->CreateString((char *)(LPCSTR)str); if (!m_Fire1.Init(&sm) || !m_Fire1.CreateObject(m_pClientDE)) { return LTFALSE; } dwFlags = g_pLTClient->GetObjectFlags(m_Fire1.GetObject()); g_pLTClient->SetObjectFlags(m_Fire1.GetObject(), dwFlags | FLAG_NOGLOBALLIGHTSCALE); m_Fire1.Update(); g_pLTClient->FreeString(sm.hstrTexture); // Create inner fire particles... sm.vColor1.Init(100.0f, 100.0f, 100.0f); sm.vColor2.Init(150.0f, 150.0f, 150.0f); sm.vMinDriftVel.Init(-2.0f, 25.0f, -2.0f); sm.vMaxDriftVel.Init(2.0f, 35.0f, 2.0f); sm.fRadius = FFX_DEFAULT_FIRE_PARTICLE_RADIUS * 0.75f * m_fSizeAdjust; sm.nNumParticles = 5; sm.fVolumeRadius = 5.0f * fVolumeAdjust; sm.fLifeTime = 100000.0f; sm.fMinParticleLife = 0.5f * m_fSizeAdjust; sm.fMaxParticleLife = 1.25f * m_fSizeAdjust; //sm.fStartParticleScale = 1.0f; //sm.fEndParticleScale = 0.5f; sm.fMinParticleLife = sm.fMinParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME : (sm.fMinParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME : sm.fMinParticleLife); sm.fMaxParticleLife = sm.fMaxParticleLife > FFX_MAX_FIRE_PARTICLE_LIFETIME ? FFX_MAX_FIRE_PARTICLE_LIFETIME : (sm.fMaxParticleLife < FFX_MIN_FIRE_PARTICLE_LIFETIME ? FFX_MIN_FIRE_PARTICLE_LIFETIME : sm.fMaxParticleLife); sm.fRadius = sm.fRadius > FFX_MAX_FIRE_PARTICLE_RADIUS ? FFX_MAX_FIRE_PARTICLE_RADIUS : sm.fRadius; str = g_pClientButeMgr->GetSpecialFXAttributeString("FireTex2"); if (str.IsEmpty()) return LTFALSE; sm.hstrTexture = g_pLTClient->CreateString((char *)(LPCSTR)str); if (!m_Fire2.Init(&sm) || !m_Fire2.CreateObject(m_pClientDE)) { return LTFALSE; } dwFlags = g_pLTClient->GetObjectFlags(m_Fire2.GetObject()); g_pLTClient->SetObjectFlags(m_Fire2.GetObject(), dwFlags | FLAG_NOGLOBALLIGHTSCALE); m_Fire2.Update(); g_pLTClient->FreeString(sm.hstrTexture); // Create the sound... if (m_cs.bCreateSound) { str = g_pClientButeMgr->GetSpecialFXAttributeString("FireSnd"); m_hSound = g_pClientSoundMgr->PlaySoundFromPos(m_cs.vPos, (char*)(LPCSTR)str, m_cs.fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, PLAYSOUND_GETHANDLE | PLAYSOUND_LOOP); } // Create the dynamic light... if (m_cs.bCreateLight) { LIGHTCREATESTRUCT light; LTFLOAT fRadiusMin = m_cs.fLightRadius; fRadiusMin = fRadiusMin < 20.0f ? 20.0f : (fRadiusMin > FFX_MAX_LIGHT_RADIUS ? FFX_MAX_LIGHT_RADIUS : fRadiusMin); light.vColor = m_cs.vLightColor; light.hServerObj = m_hServerObject; light.vOffset = m_cs.vLightOffset; light.dwLightFlags = FLAG_DONTLIGHTBACKFACING; light.fIntensityMin = 1.0f; light.fIntensityMax = 1.0f; light.nIntensityWaveform = WAVE_NONE; light.fIntensityFreq = 1.0f; light.fIntensityPhase = 0.0f; light.fRadiusMin = fRadiusMin; light.fRadiusMax = fRadiusMin * 1.1f; light.nRadiusWaveform = WAVE_FLICKER2; light.fRadiusFreq = m_cs.fLightFreq; light.fRadiusPhase = m_cs.fLightPhase; light.m_hLightAnim = INVALID_LIGHT_ANIM; if (!m_Light.Init(&light) || !m_Light.CreateObject(m_pClientDE)) { return LTFALSE; } } } return LTTRUE; }
void COpenGLES2GrassRenderer::render(CSGPGrass* pGrass) { SGPVertex_GRASS_GLES2 tempData; if( m_GrassClusterInstanceArray.size() > 0 ) { COpenGLES2GrassRenderer::Sorter CompareGrassInstance(m_pRenderDevice); m_GrassClusterInstanceArray.sort(CompareGrassInstance); uint32 nGrassClusterNum = jmin(m_GrassClusterInstanceArray.size(), INIT_GRASSCLUSTERINSTANCE_NUM); uint32 nSizeData = sizeof(SGPVertex_GRASS_GLES2) * nGrassClusterNum * (4*3); uint32 nVBOffset = (m_GrassClusterInstanceArray.size() <= INIT_GRASSCLUSTERINSTANCE_NUM) ? 0 : m_GrassClusterInstanceArray.size() - INIT_GRASSCLUSTERINSTANCE_NUM; SGPVertex_GRASS_Cluster* pGrassClusterSrc = m_GrassClusterInstanceArray.getRawDataPointer() + nVBOffset; // update Dynamic Grass Instance Buffer glBindBuffer(GL_ARRAY_BUFFER, m_nGrassClusterVBOID); glBufferData(GL_ARRAY_BUFFER, nSizeData, NULL, GL_STREAM_DRAW); SGPVertex_GRASS_GLES2* pGrassVertex = (SGPVertex_GRASS_GLES2*)m_pRenderDevice->extGlMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); for( uint32 i=0; i<nGrassClusterNum; i++ ) { tempData.vNormal[0] = ( pGrassClusterSrc[i].vPackedNormal[0] / 255.0f - 0.5f ) * 2.0f; tempData.vNormal[1] = ( pGrassClusterSrc[i].vPackedNormal[1] / 255.0f - 0.5f ) * 2.0f; tempData.vNormal[2] = ( pGrassClusterSrc[i].vPackedNormal[2] / 255.0f - 0.5f ) * 2.0f; tempData.vNormal[3] = pGrassClusterSrc[i].vPackedNormal[3] / 255.0f; tempData.vColor[0] = pGrassClusterSrc[i].vColor[0]; tempData.vColor[1] = pGrassClusterSrc[i].vColor[1]; tempData.vColor[2] = pGrassClusterSrc[i].vColor[2]; tempData.vColor[3] = pGrassClusterSrc[i].vColor[3]; tempData.LMtu = pGrassClusterSrc[i].vPosition[0] / m_pRenderDevice->GetWorldSystemManager()->getTerrain()->GetTerrainWidth(); tempData.LMtv = 1.0f - pGrassClusterSrc[i].vPosition[2] / m_pRenderDevice->GetWorldSystemManager()->getTerrain()->GetTerrainWidth(); Matrix4x4 RotMatrix; RotMatrix.Identity(); if( pGrassClusterSrc[i].vPackedNormal[1] < 250 ) { Vector3D vTerrainNormal(tempData.vNormal[0], tempData.vNormal[1], tempData.vNormal[2]); vTerrainNormal.Normalize(); float cost = tempData.vNormal[1]; Vector3D v; v.Cross( Vector3D(0,1,0), vTerrainNormal ); v.Normalize(); float sint = std::sqrt(1-cost*cost); float one_sub_cost = 1 - cost; RotMatrix._11 = v.x * v.x * one_sub_cost + cost; RotMatrix._12 = v.x * v.y * one_sub_cost + v.z * sint; RotMatrix._13 = v.x * v.z * one_sub_cost - v.y * sint; RotMatrix._21 = v.x * v.y * one_sub_cost - v.z * sint; RotMatrix._22 = v.y * v.y * one_sub_cost + cost; RotMatrix._23 = v.y * v.z * one_sub_cost + v.x * sint; RotMatrix._31 = v.x * v.z * one_sub_cost + v.y * sint; RotMatrix._32 = v.y * v.z * one_sub_cost - v.x * sint; RotMatrix._33 = v.z * v.z * one_sub_cost + cost; } for( uint32 j=0; j<4*3; j++ ) { tempData.tu = m_grassVertex[j].tu; tempData.tv = m_grassVertex[j].tv; Vector3D modelPos = Vector3D(m_grassVertex[j].x, m_grassVertex[j].y, m_grassVertex[j].z) * tempData.vNormal[3] * RotMatrix; modelPos += Vector3D(pGrassClusterSrc[i].vPosition[0], pGrassClusterSrc[i].vPosition[1], pGrassClusterSrc[i].vPosition[2]); float windAngle = m_vTimeParams.x * m_vTimeParams.y * Vector3D(pGrassClusterSrc[i].vPosition[0], pGrassClusterSrc[i].vPosition[1], pGrassClusterSrc[i].vPosition[2]).GetLength(); Vector3D vCosSin = Vector3D( std::cos(windAngle), 0, std::sin(windAngle) ); Vector3D vOffset( pGrassClusterSrc[i].vWindParams[0] * m_vWindDirForce.x * m_vWindDirForce.w, pGrassClusterSrc[i].vWindParams[1] * m_vWindDirForce.y * m_vWindDirForce.w, pGrassClusterSrc[i].vWindParams[2] * m_vWindDirForce.z * m_vWindDirForce.w ); vOffset.x += vCosSin.x * pGrassClusterSrc[i].vWindParams[0] * m_vWindDirForce.w; vOffset.y += vCosSin.y * pGrassClusterSrc[i].vWindParams[1] * m_vWindDirForce.w; vOffset.z += vCosSin.z * pGrassClusterSrc[i].vWindParams[2] * m_vWindDirForce.w; Vector3D vv = Vector3D(tempData.vNormal[0], tempData.vNormal[1], tempData.vNormal[2]) + vOffset; vv.Normalize(); modelPos += vv * tempData.vNormal[3] * (1.0f - tempData.tv); tempData.vPosition[0] = modelPos.x; tempData.vPosition[1] = modelPos.y; tempData.vPosition[2] = modelPos.z; tempData.vPosition[3] = pGrassClusterSrc[i].vPosition[3]; (*pGrassVertex) = tempData; pGrassVertex++; } } m_pRenderDevice->extGlUnmapBuffer(GL_ARRAY_BUFFER); } m_vTextureAtlas.Set( pGrass->m_fTextureAtlasNbX, pGrass->m_fTextureAtlasNbY, pGrass->m_fTextureAtlasW, pGrass->m_fTextureAtlasH ); }
void CBombProjectile::ApplyDamageOperation(IEntity *piEntity,void *pParam1,void *pParam2) { CBombProjectile *pThis=(CBombProjectile *)pParam1; SBombDamageData *pDamageData=((SBombDamageData*)pParam2); bool bProjectile=(*piEntity->GetEntityClass())=="CBulletProjectile"; if(pThis->m_piParent==NULL){return;} if(piEntity->IsRemoved()){return;} if(piEntity->GetAlignment()==pThis->m_dwAlignment){return;} if(piEntity->GetAlignment()==ENTITY_ALIGNMENT_NEUTRAL ){return;} if(piEntity->GetDamageType()==DAMAGE_TYPE_NONE && !bProjectile){return;} if(piEntity->GetHealth()<=0.0){return;} SPhysicInfo *pPhysicInfo=piEntity->GetPhysicInfo(); CVector vProjection; bool bHit=false; if(pPhysicInfo->dwBoundsType==PHYSIC_BOUNDS_TYPE_BBOX) { const std::vector<SBBox> *pvBBoxes=pPhysicInfo->pvBBoxes; if(pDamageData->playAreaPlane.Cut(pDamageData->vCameraPos,pPhysicInfo->vPosition,&vProjection)) { CVector vDist=vProjection-pThis->m_PhysicInfo.vPosition; double dDist=vDist; bHit=(dDist<pDamageData->dRadius); } for(unsigned int b=0;!bHit && pvBBoxes && b<pvBBoxes->size();b++) { CVector pVolumePoints[8]; CalcBBoxVolume(pPhysicInfo->vPosition,pPhysicInfo->vAngles,(*pvBBoxes)[b].vMins,(*pvBBoxes)[b].vMaxs,pVolumePoints); for(unsigned int x=0;!bHit && x<8;x++) { if(pDamageData->playAreaPlane.Cut(pDamageData->vCameraPos,pVolumePoints[x],&vProjection)) { CVector vDist=vProjection-pThis->m_PhysicInfo.vPosition; double dDist=vDist; bHit=(dDist<pDamageData->dRadius); } } } } else if(pPhysicInfo->dwBoundsType==PHYSIC_BOUNDS_TYPE_BSP) { const std::vector<SBBox> *pvVulnerableRegions=NULL; if(*piEntity->GetEntityClass()=="CStaticStructure") { IStaticStructure *piStaticStructure=dynamic_cast<IStaticStructure *>(piEntity); if(piStaticStructure && piStaticStructure->GetVulnerableRegions().size()){pvVulnerableRegions=&piStaticStructure->GetVulnerableRegions();} } for(double dX=-pDamageData->dRadius;dX<=pDamageData->dRadius;dX+=pThis->m_pType->m_dDamageEffectSeparation) { for(double dZ=-pDamageData->dRadius;dZ<=pDamageData->dRadius;dZ+=pThis->m_pType->m_dDamageEffectSeparation) { CVector vOffset(dX,0,dZ); if(vOffset>pDamageData->dRadius){continue;} vOffset+=CVector(pThis->m_pType->m_dDamageEffectSeparation*(drand()-0.5),0,pThis->m_pType->m_dDamageEffectSeparation*(drand()-0.5)); CVector vDirection=pThis->m_PhysicInfo.vPosition+vOffset-pDamageData->vCameraPos; CVector vDest=pThis->m_PhysicInfo.vPosition+vDirection*1000.0; CTraceInfo info=piEntity->GetTrace(pDamageData->vCameraPos,vDest); if(pThis->m_pType->m_DamageEffect.m_piParticleSystemType && info.m_bTraceHit) { CVector vTempPos=info.m_vTracePos-pPhysicInfo->vPosition; CVector vRelPos; vRelPos.c[0]=pPhysicInfo->vOwnX*vTempPos; vRelPos.c[1]=pPhysicInfo->vOwnY*vTempPos; vRelPos.c[2]=pPhysicInfo->vOwnZ*vTempPos; bool bSimpleHit=true; if(pvVulnerableRegions) { bSimpleHit=false; for(unsigned int b=0;!bSimpleHit && b<pvVulnerableRegions->size();b++) { bSimpleHit= (vRelPos.c[0]>=(*pvVulnerableRegions)[b].vMins.c[0] && vRelPos.c[0]<=(*pvVulnerableRegions)[b].vMaxs.c[0] && vRelPos.c[1]>=(*pvVulnerableRegions)[b].vMins.c[1] && vRelPos.c[1]<=(*pvVulnerableRegions)[b].vMaxs.c[1] && vRelPos.c[2]>=(*pvVulnerableRegions)[b].vMins.c[2] && vRelPos.c[2]<=(*pvVulnerableRegions)[b].vMaxs.c[2]); } } if(bSimpleHit) { bHit=true; if(pDamageData->bDamageEffect) { IParticleSystem *piParticleSystem=pThis->m_pType->m_DamageEffect.m_piParticleSystemType->CreateInstance(pThis->m_nCurrentTime); if(piParticleSystem) { piParticleSystem->SetPosition(info.m_vTracePos); pThis->m_vParticleSystems.push_back(piParticleSystem); } } } } } } } if(bHit) { if(bProjectile) { piEntity->Remove(); } else { piEntity->OnDamage(pDamageData->dDamage,pThis); } } }