コード例 #1
0
 public virtual void EndShoot(MyShootActionEnum action)
 {
     if (m_shotToolAction.HasValue)
     {
         if (m_shotToolAction.Value.HitDuration == 0)
             m_shotToolAction = null;
     }
 }
コード例 #2
0
        void GetMostEffectiveToolAction(List <MyToolActionDefinition> toolActions, out MyToolActionDefinition?bestAction, out MyToolHitCondition bestCondition)
        {
            MyCharacterDetectorComponent detectorComponent = m_owner.Components.Get <MyCharacterDetectorComponent>();
            IMyEntity hitEntity = null;
            uint      shapeKey  = 0;

            if (detectorComponent != null)
            {
                hitEntity = detectorComponent.DetectedEntity;
                shapeKey  = detectorComponent.ShapeKey;

                float hitDistance = Vector3.Distance(detectorComponent.HitPosition, detectorComponent.StartPosition);

                if (hitDistance > m_toolItemDef.HitDistance)
                {
                    hitEntity = null;
                }
            }

            bestAction    = null;
            bestCondition = new MyToolHitCondition();

            //Get most effective action
            foreach (var action in toolActions)
            {
                if (action.HitConditions != null)
                {
                    foreach (var condition in action.HitConditions)
                    {
                        if (condition.EntityType != null)
                        {
                            if (hitEntity != null)
                            {
                                string availableState = GetStateForTarget((MyEntity)hitEntity, shapeKey, condition.Component);
                                if (condition.EntityType.Contains(availableState))
                                {
                                    bestAction    = action;
                                    bestCondition = condition;
                                    return;
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            bestAction    = action;
                            bestCondition = condition;
                            return;
                        }
                    }
                }
            }
        }
コード例 #3
0
        internal void StopShooting(float hitDelaySec)
        {
            if (!IsShooting)
                return;

            m_lastHit = MySandboxGame.Static.UpdateTime;
            m_hitDelay = MyTimeSpan.FromSeconds(hitDelaySec);

            m_owner.PlayCharacterAnimation(m_shotHitCondition.Animation, MyBlendOption.Immediate, MyFrameOption.JustFirstFrame, 0.2f, m_shotHitCondition.AnimationTimeScale, false, null, true);
            m_shotToolAction = null;

            m_wasShooting = false;
        }
コード例 #4
0
        void GetPreferredToolAction(List <MyToolActionDefinition> toolActions, string name, out MyToolActionDefinition?bestAction, out MyToolHitCondition bestCondition)
        {
            bestAction    = null;
            bestCondition = new MyToolHitCondition();

            MyStringId nameId = MyStringId.GetOrCompute(name);

            foreach (var action in toolActions)
            {
                if (action.HitConditions.Length > 0)
                {
                    if (action.Name == nameId)
                    {
                        bestAction    = action;
                        bestCondition = action.HitConditions[0];
                        return;
                    }
                }
            }
        }
コード例 #5
0
        public override void UpdateAfterSimulation()
        {
            base.UpdateAfterSimulation();

            bool isShooting = IsShooting;

            if (!m_isHit && IsShooting && (MySandboxGame.Static.UpdateTime - m_lastShot > MyTimeSpan.FromSeconds(m_shotToolAction.Value.HitStart)))
            {
                IMyHandToolComponent toolComponent;
                if (m_toolComponents.TryGetValue(m_shotHitCondition.Component, out toolComponent))
                {
                    MyCharacterDetectorComponent detectorComponent = m_owner.Components.Get <MyCharacterDetectorComponent>();
                    if (detectorComponent != null)
                    {
                        if (m_shotToolAction.Value.CustomShapeRadius > 0 && detectorComponent is MyCharacterShapecastDetectorComponent)
                        {
                            var shapeCastComponent = detectorComponent as MyCharacterShapecastDetectorComponent;
                            shapeCastComponent.ShapeRadius = m_shotToolAction.Value.CustomShapeRadius;
                            shapeCastComponent.DoDetectionModel();
                            shapeCastComponent.ShapeRadius = MyCharacterShapecastDetectorComponent.DEFAULT_SHAPE_RADIUS;
                        }

                        if (detectorComponent.DetectedEntity != null)
                        {
                            MyHitInfo hitInfo = new MyHitInfo();
                            hitInfo.Position = detectorComponent.HitPosition;
                            hitInfo.Normal   = detectorComponent.HitNormal;

                            bool  isBlock = false;
                            float efficiencyMultiplier = 1.0f;
                            bool  canHit = CanHit(toolComponent, detectorComponent, ref isBlock, out efficiencyMultiplier);

                            MyDecals.HandleAddDecal(detectorComponent.DetectedEntity, hitInfo, MyDamageType.Weapon);

                            bool isHit = false;
                            if (canHit)
                            {
                                if (!string.IsNullOrEmpty(m_shotToolAction.Value.StatsEfficiency) && Owner.StatComp != null)
                                {
                                    efficiencyMultiplier *= Owner.StatComp.GetEfficiencyModifier(m_shotToolAction.Value.StatsEfficiency);
                                }

                                float efficiency = m_shotToolAction.Value.Efficiency * efficiencyMultiplier;
                                var   tool       = detectorComponent.DetectedEntity as MyHandToolBase;
                                if (isBlock && tool != null)
                                {
                                    isHit = toolComponent.Hit(tool.Owner, hitInfo, detectorComponent.ShapeKey, efficiency);
                                }
                                else
                                {
                                    isHit = toolComponent.Hit((MyEntity)detectorComponent.DetectedEntity, hitInfo, detectorComponent.ShapeKey, efficiency);
                                }

                                if (isHit && Sync.IsServer && Owner.StatComp != null)
                                {
                                    if (!string.IsNullOrEmpty(m_shotHitCondition.StatsActionIfHit))
                                    {
                                        Owner.StatComp.DoAction(m_shotHitCondition.StatsActionIfHit);
                                    }
                                    if (!string.IsNullOrEmpty(m_shotHitCondition.StatsModifierIfHit))
                                    {
                                        Owner.StatComp.ApplyModifier(m_shotHitCondition.StatsModifierIfHit);
                                    }
                                }
                            }

                            if (canHit || isBlock)  // real hit is not controlled now - there isn't any server-client synchronization of hit currently and hit is performed only at server
                            {
                                if (!string.IsNullOrEmpty(m_shotToolAction.Value.HitSound))
                                {
                                    PlaySound(m_shotToolAction.Value.HitSound);
                                }
                                else
                                {
                                    MyStringId collisionType = MyMaterialPropertiesHelper.CollisionType.Hit;
                                    bool       showParticles = false;

                                    // If it didn't play the Sound with "Hit", it will try with "Start"
                                    if (MyAudioComponent.PlayContactSound(EntityId, m_hitCue, detectorComponent.HitPosition,
                                                                          m_toolItemDef.PhysicalMaterial, detectorComponent.HitMaterial))
                                    {
                                        showParticles = true;
                                    }
                                    else if (MyAudioComponent.PlayContactSound(EntityId, m_startCue, detectorComponent.HitPosition,
                                                                               m_toolItemDef.PhysicalMaterial, detectorComponent.HitMaterial))
                                    {
                                        showParticles = true;
                                        collisionType = MyMaterialPropertiesHelper.CollisionType.Start;
                                    }

                                    if (showParticles)
                                    {
                                        MyMaterialPropertiesHelper.Static.TryCreateCollisionEffect(
                                            collisionType,
                                            detectorComponent.HitPosition,
                                            detectorComponent.HitNormal,
                                            m_toolItemDef.PhysicalMaterial, detectorComponent.HitMaterial);
                                    }
                                }

                                this.RaiseEntityEvent(MyStringHash.GetOrCompute("Hit"), new MyEntityContainerEventExtensions.HitParams(MyStringHash.GetOrCompute(m_shotHitCondition.Component), detectorComponent.HitMaterial));
                                m_soundEmitter.StopSound(true);
                            }
                        }
                    }
                }

                m_isHit = true;
            }

            if (!m_swingSoundPlayed && IsShooting && !m_isHit && (MySandboxGame.Static.UpdateTime - m_lastShot > MyTimeSpan.FromSeconds(m_shotToolAction.Value.SwingSoundStart)))
            {
                if (!string.IsNullOrEmpty(m_shotToolAction.Value.SwingSound))
                {
                    PlaySound(m_shotToolAction.Value.SwingSound);
                }
                m_swingSoundPlayed = true;
            }


            if (!isShooting && m_wasShooting)
            {
                m_owner.StopUpperCharacterAnimation(0.4f);
                m_shotToolAction = null;
            }


            m_wasShooting = isShooting;

            if (m_owner != null)
            {
                MatrixD blockingMatrix = MatrixD.CreateWorld(((MyEntity)m_owner.CurrentWeapon).PositionComp.GetPosition(), m_owner.WorldMatrix.Forward, m_owner.WorldMatrix.Up);

                ((MyBlockingBody)Physics).SetWorldMatrix(blockingMatrix);
            }


            foreach (var c in m_toolComponents.Values)
            {
                c.Update();
            }
        }
コード例 #6
0
        public virtual void Shoot(MyShootActionEnum shootAction, VRageMath.Vector3 direction, string gunAction)
        {
            m_shotToolAction   = null;
            m_wasShooting      = false;
            m_swingSoundPlayed = false;
            m_isHit            = false;

            if (!string.IsNullOrEmpty(gunAction))
            {
                switch (shootAction)
                {
                case MyShootActionEnum.PrimaryAction:
                    GetPreferredToolAction(m_toolItemDef.PrimaryActions, gunAction, out m_primaryToolAction, out m_primaryHitCondition);
                    break;

                case MyShootActionEnum.SecondaryAction:
                    GetPreferredToolAction(m_toolItemDef.SecondaryActions, gunAction, out m_secondaryToolAction, out m_secondaryHitCondition);
                    break;
                }
            }

            switch (shootAction)
            {
            case MyShootActionEnum.PrimaryAction:
                m_shotToolAction   = m_primaryToolAction;
                m_shotHitCondition = m_primaryHitCondition;
                break;

            case MyShootActionEnum.SecondaryAction:
                m_shotToolAction   = m_secondaryToolAction;
                m_shotHitCondition = m_secondaryHitCondition;
                break;

            default:
                System.Diagnostics.Debug.Fail("Unknown shooting state!");
                break;
            }

            MyTuple <ushort, MyStringHash> message;

            if (!string.IsNullOrEmpty(m_shotHitCondition.StatsAction) && m_owner.StatComp != null && !m_owner.StatComp.CanDoAction(m_shotHitCondition.StatsAction, out message))
            {
                if (MySession.Static != null && MySession.Static.LocalCharacter == m_owner && message.Item1 == MyStatLogic.STAT_VALUE_TOO_LOW && message.Item2.String.CompareTo("Stamina") == 0)
                {
                    m_notEnoughStatNotification.SetTextFormatArguments(message.Item2);
                    MyHud.Notifications.Add(m_notEnoughStatNotification);
                }
                return;
            }

            if (m_shotToolAction.HasValue)
            {
                IMyHandToolComponent toolComponent;
                if (m_toolComponents.TryGetValue(m_shotHitCondition.Component, out toolComponent))
                {
                    toolComponent.Shoot();
                }

                MyFrameOption frameOption = MyFrameOption.StayOnLastFrame;

                if (m_shotToolAction.Value.HitDuration == 0)
                {
                    frameOption = MyFrameOption.JustFirstFrame;
                }

                // Stop upper character animation called because character can have some animation set (blocking, ...).
                m_owner.StopUpperCharacterAnimation(0.1f);
                m_owner.PlayCharacterAnimation(m_shotHitCondition.Animation, MyBlendOption.Immediate, frameOption, 0.2f, m_shotHitCondition.AnimationTimeScale, false, null, true);

                if (m_owner.StatComp != null)
                {
                    if (!string.IsNullOrEmpty(m_shotHitCondition.StatsAction))
                    {
                        m_owner.StatComp.DoAction(m_shotHitCondition.StatsAction);
                    }
                    if (!string.IsNullOrEmpty(m_shotHitCondition.StatsModifier))
                    {
                        m_owner.StatComp.ApplyModifier(m_shotHitCondition.StatsModifier);
                    }
                }

                Physics.Enabled = m_shotToolAction.Value.Name == BlockId;

                m_lastShot = MySandboxGame.Static.UpdateTime;
            }
        }