public virtual void EndShoot(MyShootActionEnum action) { if (m_shotToolAction.HasValue) { if (m_shotToolAction.Value.HitDuration == 0) m_shotToolAction = null; } }
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; } } } } }
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; }
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; } } } }
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(); } }
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; } }