예제 #1
0
void Ve1ObjectChar::MoveTo(const Vec3f& newpos)
{
  m_newPos = newpos;
  m_isMoving = true;

  Vec3f dir = GetPos() - newpos;
  float sqLen = dir.SqLen();
  // TODO Check if distance is greater than last time - if so, we have missed the target!

  static const float STOP_DIST = ROConfig()->GetFloat("stop-dist", 10.0f);
  if (sqLen < STOP_DIST)
  {
    SetVel(Vec3f(0, 0, 0));
    m_isMoving = false; // Not sure why this wasn't here
  }
  // TODO enable this when we are reliably resetting sqLenLastTime, otherwise sometimes characters won't move
  /*
  else if (sqLen > sqLenLastTime)
  {
    SetVel(Vec3f(0, 0, 0));
    m_isMoving = false; // Not sure why this wasn't here
  }
  */
  else
  {
    dir.Normalise();
    SetVel(-dir * SPEED);

    // Work out direction to face
    SetDir(RadToDeg(atan2((double)m_vel.x, (double)m_vel.z)));
  }
  sqLenLastTime = sqLen;
}
예제 #2
0
int Doodad::Callback(unsigned int msg, unsigned int wParam, int lParam)
{
	switch(msg)
	{
	case ENTITYMSG_UPDATE:
		//Update waypoint
		if(m_pWayPt)
		{
			D3DXVECTOR3 destPt, target, lookDir;

			//GetCurrentLinearLoc(&destPt);
			m_pWayPt->GetCurrentCurvedLoc(&destPt, &target);

			lookDir = target - GetLoc();
			//D3DXVec3Normalize(&lookDir, &lookDir);
			SetDir(lookDir);

			D3DXVECTOR3 dir(destPt - GetLoc());
			float len = D3DXVec3Length(&dir);

			float spd = m_moveSpd.MoveUpdate(g_timeElapse);
			
			if(len > spd)
			{
				dir /= len;

				SetVel(GetVel() + (spd*dir));
			}
			//we are close enough
			//get to next waypoint node
			else
			{
				SetVel(dir);

				m_pWayPt->GotoNext();
			}
			
			//if(m_pWayPt->IsDone())
			//	RemoveWayPt();
		}
		break;

	case ENTITYMSG_ALLOWGRAVITY:
		//simply don't allow gravity
		return 0;

	case ENTITYMSG_PROFILEPREP:
		Show(wParam == 1 ? true : false);
		break;
	}

	return RETCODE_SUCCESS;
}
int PullPower::Callback(unsigned int msg, unsigned int wParam, int lParam)
{
	switch(msg)
	{
	case ENTITYMSG_UPDATE:
		{
			EntityCommon *pEntity = (EntityCommon *)IDPageQuery(GetOwner());

			if(pEntity)
			{
				////////////////////////////////////////////////////////
				//set location
				SetLoc(pEntity->GetLoc()+(m_maxLength*pEntity->GetDir()));
				
				//set direction
				SetDir(-pEntity->GetDir());

				//set vel.
				SetVel(-m_maxLength*pEntity->GetDir());

				//move it
				/*float spd = m_spd.MoveUpdate(g_timeElapse);

				m_curLength += spd;

				if(m_curLength >= m_maxLength)
				{
					//Poll ourself to death!
					SetFlag(ENTITY_FLAG_POLLDEATH, true);
				}*/
			}
		}
		break;

	case ENTITYMSG_ENTITYCOLLIDE://, (WPARAM)pEntity
		{
			//sigh...
			EntityCommon *pEntity = (EntityCommon *)wParam;

			if(pEntity->CheckFlag(ENTITY_FLAG_PULLABLE))
			{
				pEntity->SetLoc(pEntity->GetLoc());
				pEntity->SetVel(pEntity->GetVel()
							+(m_spd.MoveUpdate(g_timeElapse)*GetDir()));
			}
		}
		break;

	case ENTITYMSG_ALLOWGRAVITY:
		//simply don't allow gravity
		return 0;
	}

	return RETCODE_SUCCESS;
}
예제 #4
0
int UseMelee::Callback(unsigned int msg, unsigned int wParam, int lParam)
{
    switch(msg)
    {
    case ENTITYMSG_UPDATE:
    {
        //check to see if the owner's animation is done...
        //ENTITY_FLAG_POLLDEATH
        EntityCommon *pEntity = (EntityCommon *)IDPageQuery(GetOwner());

        if(pEntity)
        {
            hOBJ obj = pEntity->GetOBJ();

            if(OBJIsStateEnd(obj))
            {
                //Poll ourself to death!
                SetFlag(ENTITY_FLAG_POLLDEATH, true);
            }
            else
            {
                //update location and velocity
                D3DXVECTOR3 beginLoc, endLoc;

                //They better have these two joints!!!
                if(m_jBInd != -1 && m_jEInd != -1)
                {
                    //get the beginning loc
                    OBJJointGetWorldLoc(obj, m_jBInd, (float*)beginLoc);

                    //get the ending loc
                    OBJJointGetWorldLoc(obj, m_jEInd, (float*)endLoc);

                    //set origin
                    SetLoc(beginLoc);

                    //set velocity
                    SetVel(endLoc - beginLoc);
                }
            }
        }
    }
    break;

    case ENTITYMSG_ENTITYCOLLIDE://, (WPARAM)pEntity
        break;

    case ENTITYMSG_ALLOWGRAVITY:
        //simply don't allow gravity
        return 0;
    }

    return RETCODE_SUCCESS;
}
예제 #5
0
void cRBDModel::Update(const Eigen::VectorXd& pose, const Eigen::VectorXd& vel)
{
	SetPose(pose);
	SetVel(vel);

#if defined(ENABLE_RBD_PROFILER)
	printf("RBD_Update_BEG\n");
#endif
	UpdateJointSubspaceArr();
	UpdateChildParentMatArr();
	UpdateSpWorldTrans();
	UpdateMassMat();
	UpdateBiasForce();
#if defined(ENABLE_RBD_PROFILER)
	printf("RBD_Update_End\n\n");
#endif
}
예제 #6
0
void Player::OnLocationEntry()
{
  Ve1ObjectChar::OnLocationEntry();

  SceneNode* root = GetVe1SceneGraph()->GetRootNode(SceneGraph::AMJU_OPAQUE);
  if (root)
  {
    root->AddChild(m_arrow.GetPtr());
    SetArrowVis(false);
  }

  m_nameTag = new PlayerNameNode(this);
  if (m_sceneNode)
  {
    if (m_nameTag)
    {
      m_sceneNode->AddChild(m_nameTag.GetPtr());
    }

    if (m_effect)
    {
      m_sceneNode->AddChild(m_effect.GetPtr());
    }
  }

  // TODO Portal should have a heading which you should face when you appear at the destination
  m_isMoving = false; 
  SetVel(Vec3f(0, 0, 0)); // TODO walk out of doorway ?

  // TODO Set m_newPos ??

  // Set appearance
  SetLoggedIn(IsLoggedIn());

  // If we are carrying something, change its location too
  if (m_carrying)
  {
    TheObjectUpdater::Instance()->SendChangeLocationReq(m_carrying->GetId(), GetPos(), GetLocation()); 
  }
}
void CDisintegrationEffect::OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick)

//	OnUpdate
//
//	Update the effect

	{
	int i;

	//	See if the effect has faded out

	m_iTick++;
	if (m_iTick >= LIFETIME)
		{
		Destroy(removedFromSystem, CDamageSource());
		return;
		}

	//	Otherwise, update the particles

	SParticle *pParticle = m_pParticles;
	for (i = 0; i < m_iParticleCount; i++, pParticle++)
		{
		pParticle->iTicksLeft--;
		pParticle->x += pParticle->xV;
		pParticle->y += pParticle->yV;

		if (m_iTick < DISPERSE_POINT)
			{
			if (pParticle->iTicksLeft <= 0)
				InitParticle(pParticle);
			}
		}

	//	If we're moving, slow down

	SetVel(CVector(GetVel().GetX() * g_SpaceDragFactor, GetVel().GetY() * g_SpaceDragFactor));
	}
int AttackMelee::Callback(unsigned int msg, unsigned int wParam, int lParam)
{
	switch(msg)
	{
	case ENTITYMSG_UPDATE:
		{
			//check to see if the owner's animation is done...
			//ENTITY_FLAG_POLLDEATH
			EntityCommon *pEntity = (EntityCommon *)IDPageQuery(GetOwner());

			if(pEntity)
			{
				hOBJ obj = pEntity->GetOBJ();

				if(OBJIsStateEnd(obj))
				{
					//Poll ourself to death!
					SetFlag(ENTITY_FLAG_POLLDEATH, true);
				}
				else
				{
					if(m_jointInd != -1)
					{
						D3DXVECTOR3 cPt;

						//set location
						OBJJointGetWorldLoc(obj, m_jointInd, (float*)cPt);
						SetLoc(cPt);

						//set dir and velocity
						SetDir(pEntity->GetDir());
						SetVel(pEntity->GetDir());
					}
				}
			}
		}
		break;
	
	case ENTITYMSG_ENTITYCOLLIDE://, (WPARAM)pEntity
		{
			EntityCommon *pEntity = (EntityCommon *)wParam;
			EntityCommon *pOwner = (EntityCommon *)IDPageQuery(GetOwner());

			//play a sound if ind is > -1
			int sndInd = -1;

			if(pOwner)
			{
				//check to see if the owner is not the same type as entity
				//also make sure this entity is not immune
				if(pOwner->GetEntityType() != pEntity->GetEntityType()
					&& !pEntity->CheckFlag(CRE_FLAG_MELEEIMMUNE))
				{
					//check to see if the entity is a creature
					if(pEntity->GetEntityType() == ENTITY_TYPE_TATA
						|| pEntity->GetEntityType() == ENTITY_TYPE_ENEMY)
					{
						//hit this fella
						Creature *pCre = (Creature *)pEntity;

						if(!pCre->Hit())
						{
							OBJSetState(pOwner->GetOBJ(), CREANIM_IDLE1);
							pOwner->Callback(ENTITYMSG_REQUESTSOUND, SND_REQ_PROJ_HIT_WALL, (LPARAM)&sndInd);
						}
						else
							pOwner->Callback(ENTITYMSG_REQUESTSOUND, SND_REQ_PROJ_HIT_CRE, (LPARAM)&sndInd);

						SetFlag(ENTITY_FLAG_POLLDEATH, true);
					}
					else
					{
						//Poll ourself to death!
						SetFlag(ENTITY_FLAG_POLLDEATH, true);
						OBJSetState(pOwner->GetOBJ(), CREANIM_IDLE1);

						pOwner->Callback(ENTITYMSG_REQUESTSOUND, SND_REQ_PROJ_HIT_WALL, (LPARAM)&sndInd);
					}
				}
				else
				{
					//Poll ourself to death!
					SetFlag(ENTITY_FLAG_POLLDEATH, true);
					OBJSetState(pOwner->GetOBJ(), CREANIM_IDLE1);

					pOwner->Callback(ENTITYMSG_REQUESTSOUND, SND_REQ_PROJ_HIT_WALL, (LPARAM)&sndInd);
				}
			}

			//play sound
			if(sndInd > -1)
			{
				BASS_3DVECTOR pos, orient;
				memcpy(&pos, (float*)GetLoc(), sizeof(pos)); pos.z *= -1;
				memcpy(&orient, (float*)GetDir(), sizeof(orient)); orient.z *= -1;

				TaTaSoundPlay(sndInd, &pos, &orient, 0);
			}
		}
		break;

	case ENTITYMSG_WORLDCOLLIDE: //(WPARAM)hQBSP, (LPARAM)txtID
		{
			//stop the attack and set the owner back to normal state
			EntityCommon *pEntity = (EntityCommon *)IDPageQuery(GetOwner());

			if(pEntity)
			{
				OBJSetState(pEntity->GetOBJ(), CREANIM_IDLE1);

				//Poll ourself to death!
				SetFlag(ENTITY_FLAG_POLLDEATH, true);

				int sndInd=-1;
				pEntity->Callback(ENTITYMSG_REQUESTSOUND, SND_REQ_PROJ_HIT_WALL, (LPARAM)&sndInd);

				//play sound
				if(sndInd > -1)
				{
					BASS_3DVECTOR pos, orient;
					memcpy(&pos, (float*)GetLoc(), sizeof(pos)); pos.z *= -1;
					memcpy(&orient, (float*)GetDir(), sizeof(orient)); orient.z *= -1;

					TaTaSoundPlay(sndInd, &pos, &orient, 0);
				}
			}
		}
		break;

	case ENTITYMSG_DEATH:
		break;

	case ENTITYMSG_ALLOWGRAVITY:
		//simply don't allow gravity
		return 0;
	}

	return RETCODE_SUCCESS;
}
예제 #9
0
void Player::Update()
{
  if (m_isLoggedIn)
  {
    Ve1ObjectChar::Update();
  }
  else if (m_sceneNode)
  {
    Matrix m;
    m.Translate(m_pos);
    m_sceneNode->SetLocalTransform(m);

    // Set shadow AABB to same as Scene Node so we don't cull it by mistake
    m_shadow->SetAABB(*(m_sceneNode->GetAABB()));

    static const float XSIZE = ROConfig()->GetFloat("player-aabb-x", 30.0f);
    static const float YSIZE = ROConfig()->GetFloat("player-aabb-y", 100.0f);

    GetAABB()->Set(
      m_pos.x - XSIZE, m_pos.x + XSIZE,
      m_pos.y, m_pos.y + YSIZE,
      m_pos.z - XSIZE, m_pos.z + XSIZE);

    /*
    DISABLED for 2D look and feel
    TurnToFaceDir();
    */
  }

  if (m_hidden)
  {
    return;
  }

  // Stop moving if we are close enough to the destination
  // TODO This ends up happening every frame, only do it if we are moving
  if (true) //m_isMoving)
  {
    Vec3f dir = GetPos() - m_newPos;
    dir.y = 0; // ignore y coord for now
    static const float STOP_DISTANCE = ROConfig()->GetFloat("stop-dist", 20.0f);
    if (dir.SqLen() < STOP_DISTANCE) 
    {
      SetVel(Vec3f(0, 0, 0));
      m_newPos = GetPos();
      SetArrowVis(false);
      m_isMoving = false;
    }
  }
  else
  {
    //Assert(GetVel().SqLen() == 0);
  }

  if (m_sceneNode)
  {
    // Set shadow AABB to same as Scene Node so we don't cull it by mistake
    m_nameTag->SetAABB(*(m_sceneNode->GetAABB()));
  }

  if (m_ignorePortalId != -1)
  {
    GameObject* g = TheGame::Instance()->GetGameObject(m_ignorePortalId);
    if (g)
    {
      const AABB& aabb = g->GetAABB();
      if (!GetAABB()->Intersects(aabb))
      {
        // No longer intersecting portal
        m_ignorePortalId = -1;
      }
    }
    else
    {
      m_ignorePortalId = -1; // ?
    }
  }

  if (IsLocalPlayer())
  {
    TheGSMain::Instance()->SetHeartNum(m_stamina);

    if (m_stamina <= 0)
    {
      // Player now has to go back to the spaceship to regenerate or something.
      if (!m_isDead)
      {
        LurkMsg lm("You need to return to your spaceship to recover from your injuries!", 
          Colour(1, 1, 1, 1), Colour(1, 0, 0, 1), AMJU_CENTRE); 
        TheLurker::Instance()->Queue(lm);
      }

      m_isDead = true;
    }
  }
}
예제 #10
0
void CFractureEffect::OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick)

//	OnUpdate
//
//	Update the effect

	{
	//	See if the effect has faded out

	m_iTick++;
	if (m_iTick >= m_iLifeTime)
		{
		Destroy(removedFromSystem, CDamageSource());
		return;
		}

	//	Update particles

	if (m_pParticles)
		{
		SParticle *pParticle = m_pParticles;
		SParticle *pParticleEnd = pParticle + m_iParticleCount;

		//	If we have an attractor, accelerate all particles towards it

		if (m_pAttractor)
			{
			bool bParticlesLeft = false;

			//	Compute the position of the attractor in the particle
			//	coordinate system.

			CVector vDist = m_pAttractor->GetPos() - GetPos();
			int xAttract = FIXED_POINT * (int)(vDist.GetX() / g_KlicksPerPixel);
			int yAttract = -FIXED_POINT * (int)(vDist.GetY() / g_KlicksPerPixel);

			while (pParticle < pParticleEnd)
				{
				int xDelta = xAttract - pParticle->x;
				int yDelta = yAttract - pParticle->y;
				int xDist = abs(xDelta);
				int yDist = abs(yDelta);

				//	If within threshold, then particles do not move

				if (xDist < (8 * FIXED_POINT) && yDist < (8 * FIXED_POINT))
					;

				//	Otherwise, move towards attractor

				else
					{
					int iDist = Max(xDist, yDist);
					int iSpeed = 256 * 256 * FIXED_POINT / iDist;
					iSpeed = Min(iSpeed, 4 * FIXED_POINT);

					int iFade = (m_iTick > 100 ? 0 : (100 - m_iTick));
					int xV = (iSpeed * xDelta / iDist) + (iFade * pParticle->xV / 100);
					int yV = (iSpeed * yDelta / iDist) + (iFade * pParticle->yV / 100);

					pParticle->x += xV;
					pParticle->y += yV;

					bParticlesLeft = true;
					}

				pParticle++;
				}

			//	If no particles left, destroy the effect

			if (!bParticlesLeft)
				{
				Destroy(removedFromSystem, CDamageSource());
				return;
				}
			}

		//	Otherwise, follow normal trajectory

		else
			{
			while (pParticle < pParticleEnd)
				{
				pParticle->x += pParticle->xV;
				pParticle->y += pParticle->yV;

				pParticle++;
				}
			}
		}
	else
		{
		Destroy(removedFromSystem, CDamageSource());
		return;
		}

	//	If we're moving, slow down

	SetVel(CVector(GetVel().GetX() * g_SpaceDragFactor, GetVel().GetY() * g_SpaceDragFactor));
	}
예제 #11
0
void CMissile::OnUpdate (SUpdateCtx &Ctx, Metric rSecondsPerTick)

//	OnUpdate
//
//	Update the beam

{
    //	If we're already destroyed, then just update the timer until the
    //	vapor trail fades out

    if (m_fDestroyed)
    {
        //	Update the painter

        if (m_pPainter)
        {
            m_pPainter->OnUpdate();

            //	LATER: We shouldn't have to update bounds here because
            //	it is set in OnMove.

            SetBounds(m_pPainter);
        }

        //	Done?

        if (--m_iLifeLeft <= 0)
        {
            Destroy(removedFromSystem, CDamageSource());
            return;
        }
    }

    //	Otherwise, update

    else
    {
        int i;
        CSystem *pSystem = GetSystem();
        int iTick = m_iTick + GetDestiny();
        bool bDestroy = false;

        //	Accelerate, if necessary

        if (m_pDesc->m_iAccelerationFactor > 0
                && (iTick % 10 ) == 0)
        {
            if (m_pDesc->m_iAccelerationFactor < 100
                    || GetVel().Length() < m_pDesc->m_rMaxMissileSpeed)
                SetVel(GetVel() * (Metric)(m_pDesc->m_iAccelerationFactor / 100.0));
        }

        //	If we can choose new targets, see if we need one now

        if (m_pDesc->CanAutoTarget() && m_pTarget == NULL)
            m_pTarget = GetNearestEnemy(MAX_TARGET_RANGE, false);

        //	If this is a tracking missile, change direction to face the target

        if (m_pDesc->IsTrackingTime(iTick)
                && m_pTarget)
        {
            //	Get the position and velocity of the target

            CVector vTarget = m_pTarget->GetPos() - GetPos();
            CVector vTargetVel = m_pTarget->GetVel() - GetVel();

            //	Figure out which direction to move in

            int iFireAngle;
            Metric rCurrentSpeed = GetVel().Length();
            Metric rTimeToIntercept = CalcInterceptTime(vTarget, vTargetVel, rCurrentSpeed);
            if (rTimeToIntercept > 0.0)
            {
                CVector vInterceptPoint = vTarget + vTargetVel * rTimeToIntercept;
                iFireAngle = VectorToPolar(vInterceptPoint, NULL);
            }
            else
                iFireAngle = VectorToPolar(vTarget);

            //	Turn to desired direction.

            if (!AreAnglesAligned(iFireAngle, m_iRotation, 1))
            {
                int iTurn = (iFireAngle + 360 - m_iRotation) % 360;

                if (iTurn >= 180)
                {
                    int iTurnAngle = Min((360 - iTurn), m_pDesc->GetManeuverRate());
                    m_iRotation = (m_iRotation + 360 - iTurnAngle) % 360;
                }
                else
                {
                    int iTurnAngle = Min(iTurn, m_pDesc->GetManeuverRate());
                    m_iRotation = (m_iRotation + iTurnAngle) % 360;
                }
            }

            SetVel(PolarToVector(m_iRotation, rCurrentSpeed));
        }

        //	Update exhaust

        if (m_pExhaust)
        {
            if (iTick % m_pDesc->m_iExhaustRate)
            {
                if (m_pExhaust->GetCount() == m_pExhaust->GetMaxCount())
                    m_pExhaust->Dequeue();

                SExhaustParticle &New = m_pExhaust->GetAt(m_pExhaust->Queue());
                New.vPos = GetPos();
                New.vVel = GetVel();
            }

            for (int i = 0; i < m_pExhaust->GetCount(); i++)
            {
                SExhaustParticle &Particle = m_pExhaust->GetAt(i);
                Particle.vVel = m_pDesc->m_rExhaustDrag * Particle.vVel;
                Particle.vPos = Particle.vPos + Particle.vVel * g_SecondsPerUpdate;
            }
        }

        //	Update the painter

        if (m_pPainter)
        {
            m_pPainter->OnUpdate();

            //	LATER: We shouldn't have to update bounds here because
            //	it is set in OnMove.

            SetBounds(m_pPainter);
        }

        //	If we have a vapor trail and need to save rotation, do it

        if (m_pDesc->GetVaporTrailLength()
                && m_pDesc->IsTracking())
        {
            //	Compute the current rotation

            int iDirection = (m_iRotation + 180) % 360;

            //	Add the current rotation to the list of saved rotations

            if (m_pSavedRotations == NULL)
            {
                m_pSavedRotations = new int [m_pDesc->GetVaporTrailLength()];
                m_iSavedRotationsCount = 0;
            }

            int iStart = Min(m_iSavedRotationsCount, m_pDesc->GetVaporTrailLength() - 1);
            for (i = iStart; i > 0; i--)
                m_pSavedRotations[i] = m_pSavedRotations[i - 1];

            m_pSavedRotations[0] = iDirection;
            if (m_iSavedRotationsCount < m_pDesc->GetVaporTrailLength())
                m_iSavedRotationsCount++;
        }

        //	See if the missile hit anything

        if (m_fDetonate && m_pDesc->ProximityBlast())
        {
            CreateFragments(GetPos());
            bDestroy = true;
        }
        else if (m_pHit)
        {
            //	If we have fragments, then explode now

            if (m_iHitDir == -1
                    && m_pDesc->ProximityBlast()
                    && m_iTick >= m_pDesc->GetProximityFailsafe())
            {
                CreateFragments(m_vHitPos);
                bDestroy = true;
            }

            //	Otherwise, if this was a direct hit, then we do damage

            else if (m_iHitDir != -1)
            {
                SDamageCtx DamageCtx;
                DamageCtx.pObj = m_pHit;
                DamageCtx.pDesc = m_pDesc;
                DamageCtx.Damage = m_pDesc->m_Damage;
                DamageCtx.Damage.AddBonus(m_iBonus);
                DamageCtx.Damage.SetCause(m_iCause);
                if (IsAutomatedWeapon())
                    DamageCtx.Damage.SetAutomatedWeapon();
                DamageCtx.iDirection = (m_iHitDir + 360 + mathRandom(0, 30) - 15) % 360;
                DamageCtx.vHitPos = m_vHitPos;
                DamageCtx.pCause = this;
                DamageCtx.Attacker = m_Source;

                EDamageResults result = m_pHit->Damage(DamageCtx);

                //	If we hit another missile (or some small object) there is a chance
                //	that we continue

                if (result == damagePassthrough || result == damagePassthroughDestroyed)
                {
                    m_iHitPoints = m_iHitPoints / 2;
                    bDestroy = (m_iHitPoints == 0);
                }

                //	Set the missile to destroy itself after a hit, if we did not
                //	pass through

                else if (!m_fPassthrough)
                    bDestroy = true;
            }
        }

        //	See if the missile has faded out

        if (bDestroy || --m_iLifeLeft <= 0)
        {
            //	If this is a fragmentation weapon, then we explode at the end of life

            if (!bDestroy && m_pDesc->ProximityBlast())
                CreateFragments(GetPos());

            //	If we've got a vapor trail effect, then keep the missile object alive
            //	but mark it destroyed

            int iFadeLife;
            if (m_pDesc->GetVaporTrailLength())
            {
                m_fDestroyed = true;
                m_iLifeLeft = m_pDesc->GetVaporTrailLength();
            }

            //	If we've got an effect that needs time to fade out, then keep
            //	the missile object alive

            else if (m_pPainter && (iFadeLife = m_pPainter->GetFadeLifetime()))
            {
                m_pPainter->OnBeginFade();

                m_fDestroyed = true;
                m_iLifeLeft = iFadeLife;
            }

            //	Otherwise, destroy the missile

            else
            {
                Destroy(removedFromSystem, CDamageSource());
                return;
            }
        }
    }

    m_iTick++;
}
예제 #12
0
void CPlayerBall::State_KEEPERHANDS_Think()
{
	int wasOrIsinPenBoxOfTeam = m_nInPenBoxOfTeam != TEAM_NONE ? m_nInPenBoxOfTeam : m_nWasInPenBoxOfTeam;

	if (!CSDKPlayer::IsOnField(m_pPl, wasOrIsinPenBoxOfTeam))
	{
		m_pPl = GetGlobalTeam(wasOrIsinPenBoxOfTeam)->GetPlayerByPosType(POS_GK);

		if (!m_pPl)
			return State_Transition(BALL_STATE_NORMAL);

		m_pPl->SetShotButtonsReleased(false);
		m_pHoldingPlayer = m_pPl;
		m_pPl->m_pHoldingBall = this;
		m_pPl->DoServerAnimationEvent(PLAYERANIMEVENT_CARRY);
		EnablePlayerCollisions(false);
	}

	UpdateCarrier();

	Vector min = GetGlobalTeam(m_pPl->GetTeamNumber())->m_vPenBoxMin - Vector(BALL_PHYS_RADIUS, BALL_PHYS_RADIUS, 0);
	Vector max = GetGlobalTeam(m_pPl->GetTeamNumber())->m_vPenBoxMax + Vector(BALL_PHYS_RADIUS, BALL_PHYS_RADIUS, 0);

	// Ball outside the penalty box
	if (m_nInPenBoxOfTeam == TEAM_NONE)
	{
		Vector vel, pos;

		// Throw the ball towards the kick-off spot if it's behind the goal line and either would end up inside the goal or is in a map with a walled field
		if ((m_pPl->GetTeam()->m_nForward == 1 && m_vPos.y < min.y || m_pPl->GetTeam()->m_nForward == -1 && m_vPos.y > max.y)
			&& (SDKGameRules()->HasWalledField()
				|| (m_vPos.x >= m_pPl->GetTeam()->m_vGoalCenter.GetX() - SDKGameRules()->m_vGoalTriggerSize.x
					&& m_vPos.x <= m_pPl->GetTeam()->m_vGoalCenter.GetX() + SDKGameRules()->m_vGoalTriggerSize.x)))
		{
			pos = Vector(m_vPos.x, (m_pPl->GetTeam()->m_nForward == 1 ? SDKGameRules()->m_vFieldMin.GetY() - BALL_PHYS_RADIUS : SDKGameRules()->m_vFieldMax.GetY() + BALL_PHYS_RADIUS) + m_pPl->GetTeam()->m_nForward * 36, m_vPos.z);
			vel = 25 * Vector(0, m_pPl->GetTeam()->m_nForward, 0);
		}
		else
		{
			pos = m_vPos;
			vel = m_vPlVel;
		}

		SetPos(pos, false);
		SetVel(vel, 0, FL_SPIN_FORCE_NONE, BODY_PART_KEEPERHANDS, true, sv_ball_shottaker_mindelay_short.GetFloat(), true);

		return State_Transition(BALL_STATE_NORMAL);
	}

	Vector handPos;
	QAngle handAng;
	m_pPl->GetAttachment("keeperballrighthand", handPos, handAng);
	SetPos(handPos, false);
	SetAng(handAng);

	if (m_pPl->ShotButtonsReleased() && m_pPl->IsChargedshooting() && m_pPl->CanShoot())
	{
		Vector vel;
		int spinFlags;
		PlayerAnimEvent_t animEvent;

		if (m_aPlAng[PITCH] > sv_ball_keepershot_minangle.GetInt())
		{
			Vector dir;
			AngleVectors(m_aPlAng, &dir);
			vel = m_vPlForwardVel2D + dir * sv_ball_keeperthrow_strength.GetInt();
			spinFlags = FL_SPIN_FORCE_NONE;
			animEvent = PLAYERANIMEVENT_KEEPER_HANDS_THROW;
		}
		else
		{
			QAngle ang = m_aPlAng;
			ang[PITCH] = min(sv_ball_keepershot_minangle.GetFloat(), m_aPlAng[PITCH]);
			Vector dir;
			AngleVectors(m_aPlAng, &dir);
			vel = dir * GetChargedshotStrength(GetPitchCoeff(), sv_ball_chargedshot_minstrength.GetInt(), sv_ball_chargedshot_maxstrength.GetInt());
			spinFlags = FL_SPIN_PERMIT_SIDE;
			animEvent = PLAYERANIMEVENT_KEEPER_HANDS_KICK;

			if (vel.Length() > 1000)
				EmitSound("Ball.Kickhard");
			else
				EmitSound("Ball.Kicknormal");
		}

		m_pPl->DoServerAnimationEvent(animEvent);
		RemoveAllTouches();
		SetPos(Vector(m_vPlPos.x, m_vPlPos.y, m_vPlPos.z + sv_ball_bodypos_keeperhands.GetFloat()) + m_vPlForward2D * 36, false);
		SetVel(vel, 1.0f, spinFlags, BODY_PART_KEEPERHANDS, true, sv_ball_shottaker_mindelay_short.GetFloat(), true);

		return State_Transition(BALL_STATE_NORMAL);
	}
}
예제 #13
0
void CParticleEffect::OnUpdate (Metric rSecondsPerTick)

//	OnUpdate
//
//	Update the effect

	{
	int iTick = GetSystem()->GetTick() + GetDestiny();

	//	Do not bother updating everything if we are far from the POV

	bool bFarAway = false;
	if (g_pUniverse->GetPOV() 
			&& g_pUniverse->GetCurrentSystem() == GetSystem())
		{
		Metric rPOVDist2 = (GetPos() - g_pUniverse->GetPOV()->GetPos()).Length2();
		Metric rMaxUpdateDist2 = LIGHT_SECOND * LIGHT_SECOND * 3600;
		bFarAway = (rPOVDist2 > rMaxUpdateDist2);
		}

	//	Update the particles

	SParticleArray *pGroup = m_pFirstGroup;
	while (pGroup)
		{
		SParticleType *pType = pGroup->pType;

		//	Max distance for a particle in this group

		Metric rMaxDist2 = pType->rRadius * pType->rRadius;
		Metric rMinDist2 = pType->rHoleRadius * pType->rHoleRadius;

		//	If the particle field causes damage then we need to
		//	compute its average density

		int iDensity = 0;
		if (pType->m_fDamage)
			{
			Metric rRadius2 = pType->rRadius * pType->rRadius;
			Metric rArea = rRadius2 / (LIGHT_SECOND * LIGHT_SECOND);
			iDensity = (int)(4 * pGroup->iCount / rArea);
			}

		//	Get an array of objects in the particle field that
		//	may influence the particles

		CSpaceObject *Objects[ctMaxObjsInField];
		int iObjCount = 0;
		if (!bFarAway && (pType->m_fWake || pType->m_fDamage))
			{
			Metric rMaxInfluenceDist2 = rMaxDist2;
			for (int i = 0; i < GetSystem()->GetObjectCount(); i++)
				{
				CSpaceObject *pObj = GetSystem()->GetObject(i);

				if (pObj 
						&& pObj->GetCategory() == catShip
						&& pObj != this)
					{
					CVector vDist = GetPos() - pObj->GetPos();
					Metric rDist2 = vDist.Length2();

					if (rDist2 < rMaxInfluenceDist2 
							&& (pObj->GetVel().Length2() > g_KlicksPerPixel)
							&& iObjCount < ctMaxObjsInField)
						{
						Objects[iObjCount++] = pObj;

						//	See if the object should take damage

						if (pType->m_fDamage)
							{
							CVector vDeltaV = pObj->GetVel() - GetVel();
							int iSpeed = (int)(vDeltaV.Length() / g_KlicksPerPixel);
							if (iSpeed == 0)
								iSpeed = 1;

							if (mathRandom(1, 1000) < (iDensity * iSpeed))
								{
								pObj->Damage(this,
										pObj->GetPos(),
										VectorToPolar(vDeltaV),
										pType->Damage);
								}
							}
						}
					}
				}
			}

		//	If we're computing drag then we need to compute the new velocity
		//	of the whole particle system

		CVector vNewVel;
		if (pType->m_fDrag)
			vNewVel = GetVel() * g_SpaceDragFactor;

		//	Iterate over all particles

		SParticle *pParticle = pGroup->pParticles;
		SParticle *pEnd = pParticle + pGroup->iCount;
		while (pParticle < pEnd)
			{
			if (pParticle->IsValid())
				{
				//	Lifespan. If we're far away and we're regenerating,
				//	then don't bother to compute lifespan.

				if (pType->m_fLifespan 
						&& !(bFarAway && (pType->m_fRegenerate && pType->iRegenerationTimer)))
					{
					if (--pParticle->iLifeLeft == 0)
						{
						//	Do we regenerate?

						if (pType->m_fRegenerate && pType->iRegenerationTimer)
							{
							pParticle->iLifeLeft = pType->iLifespan;
							pParticle->vPos = NullVector;

							//	Speed

							Metric rSpeed = mathRandom(1, 100) * (pType->rAveSpeed / 100.0);
							if (pType->iDirection == -1)
								pParticle->vVel = PolarToVector(mathRandom(0, 359), rSpeed);
							else
								{
								int iAngle = (pType->iDirection + 360 + mathRandom(0, 2 * pType->iDirRange) - pType->iDirRange) % 360;
								pParticle->vVel = PolarToVector(iAngle, rSpeed);
								}
							}

						//	Otherwise we die

						else
							{
							pParticle->iLifeLeft = -1;
							pGroup->iAlive--;
							pParticle++;
							continue;
							}
						}
					}

				//	Update the position

				if (!bFarAway)
					{
					pParticle->vPos = pParticle->vPos + pParticle->vVel;

					//	Change the velocity to keep the particles within
					//	the radius

					if (pType->m_fMaxRadius)
						{
						Metric rDist2 = pParticle->vPos.Length2();
						if (pType->m_fMaxRadius && rDist2 > rMaxDist2)
							{
							CVector vChange = pParticle->vPos + g_KlicksPerPixel * pParticle->vPos.Perpendicular().Normal();
							pParticle->vVel = pParticle->vVel - (0.00005 * vChange);
							}
						else if (rDist2 < rMinDist2)
							{
							CVector vNormal = pParticle->vPos.Normal();
							CVector vChange = g_KlicksPerPixel * (400 * vNormal - 50 * vNormal.Perpendicular());
							pParticle->vVel = pParticle->vVel + (0.00005 * vChange);
							}
						else
							pParticle->vVel = pParticle->vVel * pType->rDampening;
						}

					if (pType->m_fDrag)
						{
						//	Compute the new absolute velocity (after drag)
						CVector vAbsolute = pType->rDampening * (pParticle->vVel + GetVel());

						//	The particle velocity is the absolute vel minus the
						//	system velocity.
						pParticle->vVel = vAbsolute - vNewVel;
						}

					//	Change the velocity based on influences from other objects

					if (pType->m_fWake && (iTick % 4) == 0)
						{
						for (int i = 0; i < iObjCount; i++)
							{
							Metric rDist2 = (Objects[i]->GetPos() - (pParticle->vPos + GetPos())).Length2();
							if (rDist2 < g_KlicksPerPixel * g_KlicksPerPixel * 1000)
								{
								if (Objects[i]->GetVel().Dot(pParticle->vVel) < Objects[i]->GetVel().Length2())
									pParticle->vVel = pParticle->vVel + 0.2 * Objects[i]->GetVel();
								}
							}
						}
					}
				}

			pParticle++;
			}

		//	Regeneration timer

		if (pType->m_fRegenerate && pType->iRegenerationTimer)
			pType->iRegenerationTimer--;

		//	If there are no more particles left alive in this group then kill
		//	the group

		if (pGroup->iAlive == 0)
			{
			SParticleArray *pNext = pGroup->pNext;
			SParticleArray *pPrev = NULL;

			//	Find the previous group

			SParticleArray *pFind = m_pFirstGroup;
			while (pFind != pGroup)
				{
				if (pPrev)
					pPrev = pPrev->pNext;
				else
					pPrev = m_pFirstGroup;

				pFind = pFind->pNext;
				}

			//	Fix up the linked list

			if (pPrev)
				pPrev->pNext = pNext;
			else
				m_pFirstGroup = pNext;

			//	Delete the group

			delete pGroup;
			pGroup = pNext;
			}

		//	Otherwise, next group

		else
			pGroup = pGroup->pNext;
		}

	//	If we have no more groups then we destroy ourselves

	if (m_pFirstGroup == NULL)
		{
		Destroy(removedFromSystem, NULL);
		return;
		}

	//	If we're moving, slow down

	SetVel(CVector(GetVel().GetX() * g_SpaceDragFactor, GetVel().GetY() * g_SpaceDragFactor));
	}
예제 #14
0
int _Spit::Callback(unsigned int msg, unsigned int wParam, int lParam)
{
	switch(msg)
	{
	case ENTITYMSG_UPDATE:
		//update velocity
		SetVel(GetDir()*m_spd.MoveUpdate(g_timeElapse));

		//update sound position
		if(m_tSnd)
		{
			BASS_3DVECTOR pos, orient, vel;

			memcpy(&pos, (float*)GetLoc(), sizeof(pos)); pos.z *= -1;
			memcpy(&orient, (float*)GetDir(), sizeof(orient)); orient.z *= -1;
			memcpy(&vel, (float*)GetVel(), sizeof(vel)); vel.z *= -1;

			BASS_ChannelSet3DPosition(m_tSnd, &pos, &orient, &vel);
		}
		break;

	case ENTITYMSG_ENTITYCOLLIDE://, (WPARAM)pEntity
		{
			EntityCommon *pEntity = (EntityCommon *)wParam;
			EntityCommon *pOwner = (EntityCommon *)IDPageQuery(GetOwner());

			//check to see if the owner is not the same type as entity
			if(pOwner)
			{
				if(pOwner->GetEntityType() != pEntity->GetEntityType())
				{
					//check to see if the entity is a creature
					if((pEntity->GetEntityType() == ENTITY_TYPE_TATA
						|| pEntity->GetEntityType() == ENTITY_TYPE_ENEMY)
						&& !pEntity->CheckFlag(CRE_FLAG_SPITIMMUNE))
					{
						//hit this fella
						Creature *pCre = (Creature *)pEntity;

						if(pCre->Hit())
						{
							int sndInd = -1;
							pOwner->Callback(ENTITYMSG_REQUESTSOUND, SND_REQ_PROJ_HIT_CRE, (LPARAM)&sndInd);

							pCre->CREPlaySound(sndInd);
						}

						SetFlag(ENTITY_FLAG_POLLDEATH, true);
					}
				}
			}

			if(!m_bBounce || m_bounceCur == m_bounceMax)
				SetFlag(ENTITY_FLAG_POLLDEATH, true);
			else
			{
				//bounce off
				gfxTrace *pTrace = (gfxTrace*)lParam;

				D3DXVECTOR3 norm(pTrace->norm), refl;

				float nd = D3DXVec3Dot(&GetDir(), &norm);

				refl = GetDir() - (2*nd*norm);

				SetDir(refl);

				m_bounceCur++;
			}
		}
		break;

	case ENTITYMSG_WORLDCOLLIDE:
		{
			if(!m_bBounce || m_bounceCur == m_bounceMax)
				SetFlag(ENTITY_FLAG_POLLDEATH, true);
			else
			{
				//bounce off
				gfxTrace *pTrace = (gfxTrace*)lParam;

				D3DXVECTOR3 norm(pTrace->norm), refl;

				float nd = D3DXVec3Dot(&GetDir(), &norm);

				refl = GetDir() - (2*nd*norm);

				SetDir(refl);

				m_bounceCur++;
			}
		}
		break;

	case ENTITYMSG_DEATH:
		//cool FX explosion
		break;

	case ENTITYMSG_ALLOWGRAVITY:
		//simply don't allow gravity
		return 0;
	}

	return RETCODE_SUCCESS;
}
예제 #15
0
void CMfxEvent::setToDefaults()
{
	SetTime( 0 );
	SetPort( 0 );
	SetChannel( 0 );

	switch (GetType())
	{
		case Note:
			SetKey( 60 );
			SetVel( 64 );
			SetDur( 120 );
			break;

		case KeyAft:
			SetKey( 60 );
			SetPressure( 0 );
			break;

		case Control:
			SetCtrlNum( CTL_MODULATION );
			SetCtrlVal( 0 );
			break;

		case Patch:
			SetBankSelectMethod( Normal );
			SetBank( BANK_NONE );
			SetPatch( 0 );
			break;

		case ChanAft:
			SetPressure( 0 );
			break;

		case Wheel:
			SetWheel( 0 );
			break;

		case RPN:
		case NRPN:
			SetCtrlNum( 0 );
			SetCtrlVal( 0 );
			break;

		case Sysx:
		case Text:
		case Lyric:
			m_hBuffer = NULL;
			break;

		case MuteMask:
			m_mfxChannel = 0;
			m_maskSet = 0;
			m_maskClear = 0;
			break;

		case VelOfs:
		case KeyOfs:
			m_mfxChannel = 0;
			m_nOfs = 0;
			break;

		case VelTrim:
		case KeyTrim:
			m_mfxChannel = 0;
			m_nTrim = 0;
			break;

		case ShortMsg:
			m_dwShortMsg = 0;
			break;
			
		default:
			ASSERT(FALSE);
			break;
	}
}
예제 #16
0
파일: dsky.cpp 프로젝트: dseagrav/NASSP
void DSKY::ProcessChannel10(ChannelValue val){
	ChannelValue10 out_val;
	char	C1, C2;

	out_val.Value = val.to_ulong();

	C1 = ValueChar(out_val.Bits.c);
	C2 = ValueChar(out_val.Bits.d);

	switch (out_val.Bits.a) {

	case 11:
		Prog[0] = C1;
		Prog[1] = C2;
		break;

	case 10:
		Verb[0] = C1;
		Verb[1] = C2;
		break;

	case 9:
		Noun[0] = C1;
		Noun[1] = C2;
		break;
	
	case 8:
		R1[1] = C2;
		break;

	case 7:
		R1[2] = C1;
		R1[3] = C2;
		if (out_val.Bits.b) {
			R1[0] = '+';
		}
		else if (R1[0] == '+') {
			R1[0] = ' ';
		}
		break;

	case 6:
		R1[4] = C1;
		R1[5] = C2;
		if (out_val.Bits.b) {
			R1[0] = '-';
		}
		else if (R1[0] == '-') {
			R1[0] = ' ';
		}
		break;

	case 5:
		R2[1] = C1;
		R2[2] = C2;
		if (out_val.Bits.b) {
			R2[0] = '+';
		}
		else if (R2[0] == '+') {
			R2[0] = ' ';
		}
		break;

	case 4:
		R2[3] = C1;
		R2[4] = C2;
		if (out_val.Bits.b) {
			R2[0] = '-';
		}
		else if (R2[0] == '-') {
			R2[0] = ' ';
		}
		break;

	case 3:
		R2[5] = C1;
		R3[1] = C2;
		break;

	case 2:
		R3[2] = C1;
		R3[3] = C2;
		if (out_val.Bits.b) {
			R3[0] = '+';
		}
		else if (R3[0] == '+') {
			R3[0] = ' ';
		}
		break;

	case 1:
		R3[4] = C1;
		R3[5] = C2;
		if (out_val.Bits.b) {
			R3[0] = '-';
		}
		else if (R3[0] == '-') {
			R3[0] = ' ';
		}
		break;

	// 12 - set light states.
	case 12:
		SetVel((out_val.Value & (1 << 2)) != 0);
		SetNoAtt((out_val.Value & (1 << 3)) != 0);
		SetAlt((out_val.Value & (1 << 4)) != 0);
		SetGimbalLock((out_val.Value & (1 << 5)) != 0);
		SetTracker((out_val.Value & (1 << 7)) != 0);
		SetProg((out_val.Value & (1 << 8)) != 0);
		break;
	}
}