private void AddUseObjectControl(MyCharacter character) { MyCharacterDetectorComponent detectorComponent = character.Components.Get <MyCharacterDetectorComponent>(); if (detectorComponent != null) { if (detectorComponent.UseObject is MyUseObjectDoorTerminal || detectorComponent.UseObject is MyUseObjectTerminal || detectorComponent.UseObject is MyUseObjectTextPanel) { m_terminalControlHelper.SetLabel(MySpaceTexts.ControlMenuItemLabel_ShowControlPanel); m_controlMenu.AddItem(m_terminalControlHelper); } else if (detectorComponent.UseObject is MyUseObjectInventory) { m_terminalControlHelper.SetLabel(MySpaceTexts.ControlMenuItemLabel_OpenInventory); m_controlMenu.AddItem(m_terminalControlHelper); } else if (detectorComponent.UseObject is MyUseObjectPanelButton) { m_terminalControlHelper.SetLabel(MySpaceTexts.ControlMenuItemLabel_SetupButtons); m_controlMenu.AddItem(m_terminalControlHelper); } //else if (character.IsUseObjectOfType<MyUseObjectWardrobe>()) //{ // m_terminalControlHelper.SetLabel(MySpaceTexts.ControlMenuItemLabel_Wardrobe); // m_controlMenu.AddItem(m_terminalControlHelper); //} } }
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; } } } } }
public override void UpdateAfterSimulation10() { base.UpdateAfterSimulation10(); GetMostEffectiveToolAction(m_toolItemDef.PrimaryActions, out m_primaryToolAction, out m_primaryHitCondition); GetMostEffectiveToolAction(m_toolItemDef.SecondaryActions, out m_secondaryToolAction, out m_secondaryHitCondition); if (MySession.Static.ControlledEntity == m_owner) { MyCharacterDetectorComponent detectorComponent = m_owner.Components.Get <MyCharacterDetectorComponent>(); bool entityDetected = false; float hitDistance = float.MaxValue; if (detectorComponent != null) { entityDetected = detectorComponent.DetectedEntity != null; hitDistance = Vector3.Distance(detectorComponent.HitPosition, PositionComp.GetPosition()); } if (hitDistance > m_toolItemDef.HitDistance) { entityDetected = false; } if (m_primaryToolAction != null && (m_primaryHitCondition.EntityType != null || entityDetected)) { MyHud.Crosshair.ChangeDefaultSprite(m_primaryToolAction.Value.Crosshair); } else if (m_secondaryToolAction != null && (m_secondaryHitCondition.EntityType != null || entityDetected)) { MyHud.Crosshair.ChangeDefaultSprite(m_secondaryToolAction.Value.Crosshair); } else { MyHud.Crosshair.ChangeDefaultSprite(MyHudTexturesEnum.crosshair); } } }
protected bool CanHit(IMyHandToolComponent toolComponent, MyCharacterDetectorComponent detectorComponent, ref bool isBlock, out float hitEfficiency) { bool canHit = true; hitEfficiency = 1.0f; MyTuple <ushort, MyStringHash> message; // TODO(GoodAI/HonzaS): Take care when merging this line. // The null check was not encountered with hand tools different from the reward/punishment tool. if (detectorComponent.HitBody != null && detectorComponent.HitBody.UserObject is MyBlockingBody) { var blocking = detectorComponent.HitBody.UserObject as MyBlockingBody; if (blocking.HandTool.IsBlocking && blocking.HandTool.m_owner.StatComp != null && blocking.HandTool.m_owner.StatComp.CanDoAction(blocking.HandTool.m_shotHitCondition.StatsActionIfHit, out message)) { blocking.HandTool.m_owner.StatComp.DoAction(blocking.HandTool.m_shotHitCondition.StatsActionIfHit); if (!string.IsNullOrEmpty(blocking.HandTool.m_shotHitCondition.StatsModifierIfHit)) { blocking.HandTool.m_owner.StatComp.ApplyModifier(blocking.HandTool.m_shotHitCondition.StatsModifierIfHit); } isBlock = true; if (!string.IsNullOrEmpty(blocking.HandTool.m_shotToolAction.Value.StatsEfficiency)) { hitEfficiency = 1.0f - blocking.HandTool.m_owner.StatComp.GetEfficiencyModifier(blocking.HandTool.m_shotToolAction.Value.StatsEfficiency); } canHit = hitEfficiency > 0.0f; MyEntityContainerEventExtensions.RaiseEntityEventOn(blocking.HandTool, MyStringHash.GetOrCompute("Hit"), new MyEntityContainerEventExtensions.HitParams(MyStringHash.GetOrCompute("Block"), this.PhysicalItemDefinition.Id.SubtypeId)); } } if (!canHit) { hitEfficiency = 0.0f; return(canHit); } if (!string.IsNullOrEmpty(m_shotHitCondition.StatsActionIfHit)) { canHit = m_owner.StatComp != null && m_owner.StatComp.CanDoAction(m_shotHitCondition.StatsActionIfHit, out message); if (!canHit) { hitEfficiency = 0.0f; return(canHit); } } float hitDistance = Vector3.Distance(detectorComponent.HitPosition, PositionComp.GetPosition()); canHit = hitDistance <= m_toolItemDef.HitDistance; if (!canHit) { hitEfficiency = 0.0f; return(canHit); } // checking of player factions MyEntity attacker = m_owner.Entity; long attackerPlayerId = m_owner.GetPlayerIdentityId(); var localPlayerFaction = MySession.Static.Factions.TryGetPlayerFaction(attackerPlayerId) as MyFaction; if (localPlayerFaction != null && !localPlayerFaction.EnableFriendlyFire) { // friendy fire isn't enabled in attacker faction IMyEntity otherPlayerEntity = detectorComponent.DetectedEntity; MyCharacter otherPlayer = otherPlayerEntity as MyCharacter; if (otherPlayer != null) { bool sameFaction = localPlayerFaction.IsMember(otherPlayer.GetPlayerIdentityId()); canHit = !sameFaction; hitEfficiency = canHit ? hitEfficiency : 0.0f; } } return(canHit); }
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(); } }