static INT get_offset (INT n) { INT i,subtreesize[50],sum,offset; /* get number of objects downtree */ sum = n; for (i=0; i<degree; i++) { GetConcentrate(i,subtreesize+i,sizeof(INT)); sum += subtreesize[i]; } /* get offset */ if (me==master) { offset = 0; } else { Concentrate(&sum,sizeof(INT)); GetSpread(&offset,sizeof(INT)); } /* send offsets for downtree nodes */ sum = offset+n; for (i=0; i<degree; i++) { Spread(i,&sum,sizeof(INT)); sum += subtreesize[i]; } return(offset); }
//----------------------------------------------------- void CThrow::ThrowObject(IEntity* pEntity, IPhysicalEntity* pPE) { bool strengthMode = false; CPlayer *pPlayer = static_cast<CPlayer*>(m_pWeapon->GetOwnerActor()); if (pPlayer) { // Report throw to AI system. if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI()) { SAIEVENT AIevent; AIevent.targetId = pEntity->GetId(); pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_THROW, &AIevent); } } Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 dir = ApplySpread(GetFiringDir(hit, pos), GetSpread()); Vec3 vel = GetFiringVelocity(dir); float speed = 12.0f; if(strengthMode) speed *= m_pShared->throwparams.strenght_scale; speed = max(2.0f, speed); pe_params_pos ppos; ppos.pos = pEntity->GetWorldPos(); pPE->SetParams(&ppos); if(CheckForIntersections(pPE,dir)) { Matrix34 newTM = pEntity->GetWorldTM(); newTM.SetTranslation(newTM.GetTranslation()-(dir*0.4f)); pEntity->SetWorldTM(newTM,ENTITY_XFORM_POS); } else { pe_action_set_velocity asv; asv.v = (dir*speed)+vel; AABB box; pEntity->GetWorldBounds(box); Vec3 finalW = -gEnv->pSystem->GetViewCamera().GetMatrix().GetColumn0()*(8.0f/max(0.1f,box.GetRadius())); finalW.x *= Random(0.5f,1.3f); finalW.y *= Random(0.5f,1.3f); finalW.z *= Random(0.5f,1.3f); asv.w = finalW; //asv.w = Vec3(Random(-4.5f,3.5f),Random(-1.75f,2.5f),Random(-1.5f,2.2f)); pPE->Action(&asv); } SEntityEvent entityEvent; entityEvent.event = ENTITY_EVENT_PICKUP; entityEvent.nParam[0] = 0; if (pPlayer) entityEvent.nParam[1] = pPlayer->GetEntityId(); entityEvent.fParam[0] = speed; pEntity->SendEvent( entityEvent ); }
void CRecoil::UpdateSpread(bool weaponFired, bool weaponFiring, float frameTime) { const bool isFiring = m_singleShot ? weaponFired : weaponFiring; const float decay = isFiring ? m_spreadParams.decay : m_spreadParams.end_decay; const float frameDecay = (float)__fsel(-decay, 0.0f, ((m_spreadParams.max - m_spreadParams.min) * __fres(decay + FLT_EPSILON)) * frameTime); float newSpread = clamp(m_spread - frameDecay, m_spreadParams.min, (m_spreadParams.max * m_maxSpreadMultiplier)); if(newSpread < m_spreadParams.max) { m_maxSpreadMultiplier = 1.f; } m_spread = newSpread; CRecoilDebugDraw::DebugSpread(GetSpread()); }
//----------------------------------------------------- void CThrow::ThrowLivingEntity(IEntity* pEntity, IPhysicalEntity* pPE) { Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 dir = ApplySpread(GetFiringDir(hit, pos), GetSpread()); Vec3 vel = GetFiringVelocity(dir); CPlayer *pPlayer = static_cast<CPlayer*>(m_pWeapon->GetOwnerActor()); if(pPlayer) { float speed = 8.0f; dir.Normalize(); if(CheckForIntersections(pPE,dir)) { Matrix34 newTM = pEntity->GetWorldTM(); newTM.SetTranslation(newTM.GetTranslation()-(dir*0.6f)); pEntity->SetWorldTM(newTM,ENTITY_XFORM_POS); } { pe_action_set_velocity asv; asv.v = (dir*speed)+vel; pPE->Action(&asv); // [anton] use thread safe=1 (immediate) if the character is still a living entity at this stage, // but will be ragdollized during the same frame pe_params_articulated_body pab; pab.bCheckCollisions = 1; // was set to 0 while carrying pPE->SetParams(&pab); } // Report throw to AI system. if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI()) { SAIEVENT AIevent; AIevent.targetId = pEntity->GetId(); pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_STUNT_THROW_NPC, &AIevent); } } }
bool CShotgun::Shoot(bool resetAnimation, bool autoreload/* =true */, bool noSound /* =false */) { IEntityClass *ammo = m_pShared->fireparams.ammo_type_class; int ammoCount = m_pWeapon->GetAmmoCount(ammo); if(m_pShared->fireparams.clip_size==0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor?pActor->IsPlayer():false; if(!CanFire(true)) { if((ammoCount <= 0) && (!m_reloading)) { m_pWeapon->PlayAction(m_pShared->actions.empty_clip); //Auto reload m_pWeapon->Reload(); } return false; } else if(m_pWeapon->IsWeaponLowered()) { m_pWeapon->PlayAction(m_pShared->actions.null_fire); return false; } if(m_reloading) { if(m_pWeapon->IsBusy()) m_pWeapon->SetBusy(false); if(CanFire(true) && !m_break_reload) { m_break_reload = true; m_pWeapon->RequestCancelReload(); } return false; } // Aim assistance m_pWeapon->AssistAiming(); const char *action = m_pShared->actions.fire_cock.c_str(); if(ammoCount == 1 || (m_pShared->fireparams.no_cock && m_pWeapon->IsZoomed())) action = m_pShared->actions.fire.c_str(); m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default|CItem::eIPAF_RestartAnimation|CItem::eIPAF_CleanBlending); Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 fdir = ApplySpread(GetFiringDir(hit, pos), GetSpread()); Vec3 vel = GetFiringVelocity(fdir); Vec3 dir; CheckNearMisses(hit, pos, fdir, WEAPON_HIT_RANGE, m_pShared->shotgunparams.spread); bool serverSpawn = m_pWeapon->IsServerSpawn(ammo); // SHOT HERE for(int i = 0; i < m_pShared->shotgunparams.pellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(ammo, false); if(pAmmo) { dir = ApplySpread(fdir, m_pShared->shotgunparams.spread); int hitTypeId = g_pGame->GetGameRules()->GetHitTypeId(m_pShared->fireparams.hit_type.c_str()); pAmmo->SetParams(m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_pShared->shotgunparams.pelletdamage, hitTypeId, playerIsShooter?m_pShared->fireparams.damage_drop_per_meter:0.0f, m_pShared->fireparams.damage_drop_min_distance); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->Launch(pos, dir, vel); if((!m_pShared->tracerparams.geometry.empty() || !m_pShared->tracerparams.effect.empty()) && (ammoCount==GetClipSize() || (ammoCount%m_pShared->tracerparams.frequency==0))) { EmitTracer(pos,hit,false); } m_projectileId = pAmmo->GetEntity()->GetId(); } } m_pWeapon->OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel); if(m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_pShared->shotgunparams.pellets, (void *)m_pWeapon->GetEntityId())); } MuzzleFlashEffect(true); RejectEffect(); m_fired = true; m_next_shot += m_next_shot_dt; m_zoomtimeout = m_next_shot + 0.5f; ammoCount--; if(playerIsShooter) { if(pActor->InZeroG()) { IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy *)pActor->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS); SMovementState ms; pActor->GetMovementController()->GetMovementState(ms); CPlayer *plr = (CPlayer *)pActor; if(m_recoilparams.back_impulse > 0.0f) { Vec3 impulseDir = ms.aimDirection * -1.0f; Vec3 impulsePos = ms.pos; float impulse = m_recoilparams.back_impulse; pPhysicsProxy->AddImpulse(-1, impulsePos, impulseDir * impulse * 100.0f, true, 1.0f); } if(m_recoilparams.angular_impulse > 0.0f) { float impulse = m_recoilparams.angular_impulse; pActor->AddAngularImpulse(Ang3(0,impulse,0), 1.0f); } } if(pActor->IsClient()) if(gEnv->pInput) gEnv->pInput->ForceFeedbackEvent(SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.15f, 0.0f, fabsf(m_recoilparams.back_impulse)*3.0f)); } if(m_pShared->fireparams.clip_size != -1) { if(m_pShared->fireparams.clip_size!=0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } if((ammoCount<1) && !m_pShared->fireparams.slider_layer.empty()) { const char *slider_back_layer = m_pShared->fireparams.slider_layer.c_str(); m_pWeapon->PlayLayer(slider_back_layer, CItem::eIPAF_Default|CItem::eIPAF_NoBlend); } if(OutOfAmmo()) { m_pWeapon->OnOutOfAmmo(ammo); if(autoreload) { m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<ScheduleReload>::Create(m_pWeapon), false); } } m_pWeapon->RequestShoot(ammo, pos, dir, vel, hit, 1.0f, 0, false); return true; }
int NotifyTwoWave (NOTIFY_INFO *allInfos, int lastInfo, int exception) { NOTIFY_INFO *newInfos; int l, i, j, n, unknownInfos, myInfos; int local_exception = exception; #if DebugNotify<=4 printf("%4d: NotifyTwoWave, lastInfo=%d\n", me, lastInfo); fflush(stdout); #endif /* BOTTOM->TOP WAVE */ /* get local Info lists from downtree */ for(l=degree-1; l>=0; l--) { GetConcentrate(l, &n, sizeof(int)); if (n<0) { /* exception from downtree, propagate */ if (-n > local_exception) local_exception = -n; } if (lastInfo+n >= maxInfos) { DDD_PrintError('E', 6321, "msg-info array overflow in NotifyTwoWave"); local_exception = EXCEPTION_NOTIFY; /* receive data, but put it onto dummy position */ GetConcentrate(l, allInfos, n*sizeof(NOTIFY_INFO)); } else { if (n>0) GetConcentrate(l, &(allInfos[lastInfo]), n*sizeof(NOTIFY_INFO)); } /* construct routing table */ for(i=0; i<n; i++) theRouting[allInfos[lastInfo+i].from] = l; if (n>0) lastInfo += n; } if (! local_exception) { /* determine target direction in tree */ /* TODO: eventually extra solution for root node! (it knows all flags are MYSELF or KNOWN!) */ qsort(allInfos, lastInfo, sizeof(NOTIFY_INFO), sort_XferInfos); i = j = 0; unknownInfos = lastInfo; myInfos = 0; while (i<lastInfo && allInfos[j].to==PROC_INVALID_TEMP) { if (allInfos[j].from==allInfos[i].to) { allInfos[i].flag = (allInfos[i].to==me) ? MYSELF : KNOWN; unknownInfos--; if (allInfos[i].to==me) myInfos++; i++; } else { if (allInfos[j].from<allInfos[i].to) j++; else i++; } } qsort(allInfos, lastInfo, sizeof(NOTIFY_INFO), sort_XferFlags); /* send local Info list uptree, but only unknown Infos */ newInfos = &allInfos[lastInfo-unknownInfos]; Concentrate(&unknownInfos, sizeof(int)); Concentrate(newInfos, unknownInfos*sizeof(NOTIFY_INFO)); lastInfo -= unknownInfos; #if DebugNotify<=1 for(i=0; i<unknownInfos; i++) { printf("%4d: NotifyTwoWave, " "send uptree unknown %d/%d (%d|%d;%d)\n", me, i, unknownInfos, newInfos[i].to, newInfos[i].from, newInfos[i].size); } #endif } else { /* we have an exception somewhere in the processor tree */ /* propagate it */ int neg_exception = -local_exception; Concentrate(&neg_exception, sizeof(int)); /* don't need to send data now */ } #if DebugNotify<=3 printf("%4d: NotifyTwoWave, wave 1 ready\n", me); fflush(stdout); #endif /* TOP->BOTTOM WAVE */ /* get Infos local to my subtree from uptree */ unknownInfos = 0; GetSpread(&unknownInfos, sizeof(int)); if (unknownInfos<0) { /* exception from downtree, propagate */ if (-unknownInfos > local_exception) local_exception = -unknownInfos; } if (unknownInfos>0) { GetSpread(newInfos, unknownInfos*sizeof(NOTIFY_INFO)); lastInfo += unknownInfos; } if (! local_exception) { /* sort Infos according to routing */ qsort(allInfos, lastInfo, sizeof(NOTIFY_INFO), sort_XferRouting); #if DebugNotify<=1 for(i=0; i<lastInfo; i++) { printf("%4d: NotifyTwoWave, " "sorted for routing %d/%d (%d|%d;%d)\n", me, i, lastInfo, allInfos[i].to, allInfos[i].from, allInfos[i].size); } #endif /* send relevant Infos downtree */ i = 0; unknownInfos = lastInfo; while ((i<unknownInfos)&&(allInfos[i].to==me)) i++; lastInfo = i; for(l=0; l<degree; l++) { j = i; while ((i<unknownInfos)&&(theRouting[allInfos[i].to]==l)) i++; j = i-j; Spread(l, &j, sizeof(int)); if (j>0) Spread(l, &allInfos[i-j], j*sizeof(NOTIFY_INFO)); } /* reuse theDescs-array for registering messages to be received */ for(i=0; i<lastInfo; i++) { theDescs[i].proc = allInfos[i].from; theDescs[i].size = allInfos[i].size; } #if DebugNotify<=3 printf("%4d: NotifyTwoWave, " "wave 2 ready, nRecv=%d\n", me, lastInfo); fflush(stdout); #endif } else { /* we received an exception from uptree, propagate it */ for(l=0; l<degree; l++) { int neg_exception = -local_exception; Spread(l, &neg_exception, sizeof(int)); /* dont send any data */ } #if DebugNotify<=3 printf("%4d: NotifyTwoWave, " "wave 2 ready, Exception=%d\n", me, local_exception); fflush(stdout); #endif return(-local_exception); } return(lastInfo); }
/// NAKAGAMI String NakagamiRand::Name() const { return "Nakagami(" + toStringWithPrecision(GetShape()) + ", " + toStringWithPrecision(GetSpread()) + ")"; }