public static CastHit?GetClosestFootSupportPosition(MyEntity characterEntity, MyEntity characterTool, Vector3 from, Vector3 up, Vector3 footDimension, Matrix WorldMatrix, float castDownLimit, float castUpLimit, uint raycastFilterLayer = 0) { bool flag = false; CastHit hit = new CastHit(); MatrixD matrix = WorldMatrix; Vector3 zero = Vector3.Zero; matrix.Translation = Vector3.Zero; zero = (Vector3)Vector3.Transform(zero, matrix); matrix.Translation = (from + (up * castUpLimit)) + zero; Vector3 vector1 = new Vector3(0f, footDimension.Y / 2f, 0f); Vector3 vector4 = new Vector3(0f, footDimension.Y / 2f, -footDimension.Z); Vector3 worldCoord = from + (up * castUpLimit); Vector3 pointTo = from - (up * castDownLimit); if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTLINE) { MyRenderProxy.DebugDrawText3D(worldCoord + zero, "Cast line", Color.White, 1f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); MyRenderProxy.DebugDrawLine3D(worldCoord + zero, pointTo + zero, Color.White, Color.White, false, false); } if (MyFakes.ENABLE_FOOT_IK_USE_HAVOK_RAYCAST) { MyPhysics.HitInfo info; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTLINE) { MyRenderProxy.DebugDrawText3D(worldCoord, "Raycast line", Color.Green, 1f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); MyRenderProxy.DebugDrawLine3D(worldCoord, pointTo, Color.Green, Color.Green, false, false); } if (MyPhysics.CastRay(worldCoord, pointTo, out info, raycastFilterLayer, true)) { flag = true; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) { MyRenderProxy.DebugDrawSphere(info.Position, 0.02f, Color.Green, 1f, false, false, true, false); MyRenderProxy.DebugDrawText3D(info.Position, "RayCast hit", Color.Green, 1f, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_TOP, -1, false); } if (Vector3.Dot((Vector3)info.Position, up) > Vector3.Dot(hit.Position, up)) { hit.Position = (Vector3)info.Position; hit.Normal = info.HkHitInfo.Normal; } } } if (flag) { return(new CastHit?(hit)); } return(null); }
// Update is called once per frame void Update() { //Prevent AIController from updating anything if the game is paused if (Time.timeScale == 0) { return; } //If the pawn is null and respawning is allowed create a new one if (pawn == null) { return; } if (pawn.isAlive == false) { return; } if (tf == null) { return; } target = SetTarget(); if (target == null) { return; } //Set all desired values sight = pawn.GetComponentInChildren <Sight>(); //pawn.stats = stats; currentHealth = maxHealth; pawn.turnSpeed = angularSpeed; pawn.forwardSpeed = forwardSpeed; MovementManager(); //Show the values in the inspector sight.target = target; targetInSight = sight.TargetInSight(); sight.viewDistance = sightDistance; castHit = (CastHit)CanMoveForward(); sight.fieldOfView = fieldOfView; canHear = CanHear(); }
/// <summary> /// Finds the closest foot support position using raycast - should raycast from start and from end of the foot /// </summary> /// <param name="from">Vector3 from - the world coordinate from witch to ray cast - usually the foot world position on the ground</param> /// <param name="up">Vector3 up - defining the world up vector used to raycast to the ground</param> /// <param name="WorldMatrix">is the world matrix of the model</param> /// <param name="castUpLimit">is the height from where we start casting</param> /// <param name="castDownLimit">is the height to how much deep we cast</param> /// <param name="footDimension">this is the foot dimension, used to create shape cast and also ankle's height, X = width, Z = length, Y = height</param> /// <returns>returns CashHit if hit or null otherwise</returns> public static CastHit? GetClosestFootSupportPosition(MyEntity characterEntity, MyEntity characterTool, Vector3 from, Vector3 up, Vector3 footDimension, Matrix WorldMatrix, float castDownLimit, float castUpLimit, uint raycastFilterLayer = 0) { bool gotHit = false; CastHit hit = new CastHit(); MatrixD matrix = WorldMatrix; Vector3 footTranslationFromAnkle = Vector3.Zero;//new Vector3(0, footDimension.Y, - footDimension.Y + footDimension.X); // assunming the -Z is facing front // set the proper translation matrix.Translation = Vector3.Zero; // just keep the matrix's orientation etc. footTranslationFromAnkle = Vector3.Transform(footTranslationFromAnkle, matrix); // get it to the world matrix.Translation = from + up * castUpLimit + footTranslationFromAnkle; // set the matrix translation to position from where we cast - we need to shift from the ankle // our shape cast returned data structure //HkContactPointData? cpd = null; //// do the foot cast shape, raycast sometimes don't return a value and we need to make sure that we do nut fall into hole //HkShape shape = new HkBoxShape(footDimension * 0.5f); Vector3 capsA = new Vector3(0, footDimension.Y / 2, 0); Vector3 capsB = new Vector3(0, footDimension.Y / 2, -footDimension.Z); //capsA = Vector3.Transform(capsA, WorldMatrix.GetOrientation()); //capsB = Vector3.Transform(capsB, WorldMatrix.GetOrientation()); //HkShape shape = new HkCapsuleShape(capsA, capsB, footDimension.X / 2); Vector3 castFrom = from + up * castUpLimit; Vector3 castTo = from - up * castDownLimit; //cpd = MyPhysics.CastShapeReturnContactData(castTo + footTranslationFromAnkle, shape, ref matrix, Physics.CharacterProxy.CharacterCollisionFilter, 0.0f); //var hit = MyPhysics.CastRay(castFrom, castTo, out position, out normal, Physics.CharacterProxy.CharacterCollisionFilter, true); //LineD castLine = new LineD(castFrom, castTo); //var result = MyEntities.GetIntersectionWithLine(ref castLine, characterEntity, characterTool, true, false, true); //if (result != null) //{ // hit.Position = result.Value.IntersectionPointInWorldSpace; // hit.Normal = result.Value.NormalInWorldSpace; // gotHit = true; // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // VRageRender.MyRenderProxy.DebugDrawSphere(hit.Position, 0.02f, Color.Gray, 1, false); // VRageRender.MyRenderProxy.DebugDrawText3D(hit.Position, "Entity Intersection hit", Color.Gray, 1, false); // } //} if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTLINE) { VRageRender.MyRenderProxy.DebugDrawText3D(castFrom + footTranslationFromAnkle, "Cast line", Color.White, 1, false); VRageRender.MyRenderProxy.DebugDrawLine3D(castFrom + footTranslationFromAnkle, castTo + footTranslationFromAnkle, Color.White, Color.White, false); } if (MyFakes.ENABLE_FOOT_IK_USE_HAVOK_RAYCAST) { // do the ray cast also, because ground may not be flat and we will use this to correct values just using raycast, this takes in consideration convex shape radius and ignores it MyPhysics.HitInfo hitInfo; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTLINE) { VRageRender.MyRenderProxy.DebugDrawText3D(castFrom, "Raycast line", Color.Green, 1, false); VRageRender.MyRenderProxy.DebugDrawLine3D(castFrom, castTo, Color.Green, Color.Green, false); } if (MyPhysics.CastRay(castFrom, castTo, out hitInfo, raycastFilterLayer, true)) { gotHit = true; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) { VRageRender.MyRenderProxy.DebugDrawSphere(hitInfo.Position, 0.02f, Color.Green, 1, false); VRageRender.MyRenderProxy.DebugDrawText3D(hitInfo.Position, "RayCast hit", Color.Green, 1, false); } // this is hack, if RayCast returns a hit above the graphics cast, take this one if (Vector3.Dot(hitInfo.Position, up) > Vector3.Dot(hit.Position, up)) { hit.Position = hitInfo.Position; hit.Normal = hitInfo.HkHitInfo.Normal; } } } // // now we need to recalculate the hit position to center // cp.HitPosition = from - Vector3.Dot(WorldMatrix.Translation - cp.HitPosition, up) * up; // //cp.HitPosition.Interpolate3(castFrom, castTo, cp.DistanceFraction); // //cp.HitPosition -= footTranslationFromAnkle; // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // VRageRender.MyRenderProxy.DebugDrawSphere(cp.HitPosition, 0.03f, Color.Violet, 1, false); // VRageRender.MyRenderProxy.DebugDrawText3D(cp.HitPosition, "ShapeCast hit Centered", Color.Violet, 1, false); // } // // shape cast correction using the normal // //float dotProductAbs = WorldMatrix.Forward.Dot(cp.Normal); // //cp.HitPosition -= WorldMatrix.Up * (1 - dotProductAbs) * footDimension.Y; // // draw shape and ray cast hits // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // matrix.Translation = cp.HitPosition; // VRageRender.MyRenderProxy.DebugDrawOBB(Matrix.CreateScale(footDimension) * matrix, Color.White, 1, false, false); // VRageRender.MyRenderProxy.DebugDrawCapsule(Vector3.Transform(capsA, WorldMatrix.GetOrientation()) + cp.HitPosition, Vector3.Transform(capsB, WorldMatrix.GetOrientation()) + cp.HitPosition, footDimension.X, Color.Red, false); // } // // use raycast to correct position // //if (hit) // //{ // // // draw shape and ray cast hits // // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // // { // // VRageRender.MyRenderProxy.DebugDrawSphere(position, 0.02f, Color.Green, 1, false, false); // // VRageRender.MyRenderProxy.DebugDrawText3D(position, "RayCast hit", Color.Green, 1, false); // // } // // // shift the foot up for the ankle height according to the normal orientation // // //float dotProductAbs = Math.Abs( WorldMatrix.Forward.Dot(normal)); // // //{ // // // // get the difference between shape and ray cast and set the position // // // Vector3 difference = (position - cp.HitPosition) * (dotProductAbs); // // // cp.HitPosition = position - difference; // prefer shapecast when the ground is on ankle // // //} // // cp.HitPosition.Interpolate3(cp.HitPosition, position, Vector3.Dot(WorldMatrix.Up, normal)); // // //cp.Normal = normal; // //} // // where will be final foot if not ankle's shifted // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // matrix.Translation = cp.HitPosition; // VRageRender.MyRenderProxy.DebugDrawSphere(cp.HitPosition, 0.02f, Color.Red, 1, false, false); // VRageRender.MyRenderProxy.DebugDrawText3D(cp.HitPosition, "Final hit", Color.Red, 1, false); // VRageRender.MyRenderProxy.DebugDrawLine3D(cp.HitPosition, cp.HitPosition + cp.Normal, Color.YellowGreen, Color.YellowGreen, false); // VRageRender.MyRenderProxy.DebugDrawOBB(Matrix.CreateScale(footDimension) * matrix, Color.Cyan, 1, false, false); // } //} return gotHit ? new CastHit?(hit) : null; }
public static bool Prefix(AcidDamageEffect __instance, DamageAccumulation accum, IDamageReceiver recv, Vector3 damageOrigin, Vector3 impactForce, CastHit impactHit) { try { if (!Mod.Settings.Acid) { return(true); } var currentArmor = recv.GetArmor().Value; var hasArmor = currentArmor > 0; var totalDamage = accum.Amount * accum.SourceMultiplier; var armorDamage = 0f; if (hasArmor) { armorDamage = Math.Min(totalDamage, currentArmor); } var healthDamage = totalDamage - armorDamage; //FileLog.Log($"({accum.Amount} * {accum.SourceMultiplier}) hit on {recv.GetDisplayName()}\ncurrentArmor {currentArmor}\ntotalDamage {totalDamage}\narmorDamage {armorDamage}\nhealthDamage {healthDamage}"); var data = new DamageAccumulation.TargetData { Target = recv, AmountApplied = totalDamage, DamageResult = new DamageResult { Source = __instance.Source, ArmorDamage = armorDamage, HealthDamage = healthDamage, ImpactForce = impactForce, ImpactHit = impactHit, DamageOrigin = damageOrigin, DamageTypeDef = __instance.AcidDamageEffectDef.DamageTypeDef } }; accum.AddGeneratedTarget(data); } catch (Exception e) { FileLog.Log(e.ToString()); } return(false); }
/// <summary> /// Finds the closest foot support position using raycast - should raycast from start and from end of the foot /// </summary> /// <param name="from">Vector3 from - the world coordinate from witch to ray cast - usually the foot world position on the ground</param> /// <param name="up">Vector3 up - defining the world up vector used to raycast to the ground</param> /// <param name="WorldMatrix">is the world matrix of the model</param> /// <param name="castUpLimit">is the height from where we start casting</param> /// <param name="castDownLimit">is the height to how much deep we cast</param> /// <param name="footDimension">this is the foot dimension, used to create shape cast and also ankle's height, X = width, Z = length, Y = height</param> /// <returns>returns CashHit if hit or null otherwise</returns> public static CastHit?GetClosestFootSupportPosition(MyEntity characterEntity, MyEntity characterTool, Vector3 from, Vector3 up, Vector3 footDimension, Matrix WorldMatrix, float castDownLimit, float castUpLimit, uint raycastFilterLayer = 0) { bool gotHit = false; CastHit hit = new CastHit(); MatrixD matrix = WorldMatrix; Vector3 footTranslationFromAnkle = Vector3.Zero;//new Vector3(0, footDimension.Y, - footDimension.Y + footDimension.X); // assunming the -Z is facing front // set the proper translation matrix.Translation = Vector3.Zero; // just keep the matrix's orientation etc. footTranslationFromAnkle = Vector3.Transform(footTranslationFromAnkle, matrix); // get it to the world matrix.Translation = from + up * castUpLimit + footTranslationFromAnkle; // set the matrix translation to position from where we cast - we need to shift from the ankle // our shape cast returned data structure //HkContactPointData? cpd = null; //// do the foot cast shape, raycast sometimes don't return a value and we need to make sure that we do nut fall into hole //HkShape shape = new HkBoxShape(footDimension * 0.5f); Vector3 capsA = new Vector3(0, footDimension.Y / 2, 0); Vector3 capsB = new Vector3(0, footDimension.Y / 2, -footDimension.Z); //capsA = Vector3.Transform(capsA, WorldMatrix.GetOrientation()); //capsB = Vector3.Transform(capsB, WorldMatrix.GetOrientation()); //HkShape shape = new HkCapsuleShape(capsA, capsB, footDimension.X / 2); Vector3 castFrom = from + up * castUpLimit; Vector3 castTo = from - up * castDownLimit; //cpd = MyPhysics.CastShapeReturnContactData(castTo + footTranslationFromAnkle, shape, ref matrix, Physics.CharacterProxy.CharacterCollisionFilter, 0.0f); //var hit = MyPhysics.CastRay(castFrom, castTo, out position, out normal, Physics.CharacterProxy.CharacterCollisionFilter, true); //LineD castLine = new LineD(castFrom, castTo); //var result = MyEntities.GetIntersectionWithLine(ref castLine, characterEntity, characterTool, true, false, true); //if (result != null) //{ // hit.Position = result.Value.IntersectionPointInWorldSpace; // hit.Normal = result.Value.NormalInWorldSpace; // gotHit = true; // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // VRageRender.MyRenderProxy.DebugDrawSphere(hit.Position, 0.02f, Color.Gray, 1, false); // VRageRender.MyRenderProxy.DebugDrawText3D(hit.Position, "Entity Intersection hit", Color.Gray, 1, false); // } //} if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTLINE) { VRageRender.MyRenderProxy.DebugDrawText3D(castFrom + footTranslationFromAnkle, "Cast line", Color.White, 1, false); VRageRender.MyRenderProxy.DebugDrawLine3D(castFrom + footTranslationFromAnkle, castTo + footTranslationFromAnkle, Color.White, Color.White, false); } if (MyFakes.ENABLE_FOOT_IK_USE_HAVOK_RAYCAST) { // do the ray cast also, because ground may not be flat and we will use this to correct values just using raycast, this takes in consideration convex shape radius and ignores it Vector3D position; Vector3 normal; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTLINE) { VRageRender.MyRenderProxy.DebugDrawText3D(castFrom, "Raycast line", Color.Green, 1, false); VRageRender.MyRenderProxy.DebugDrawLine3D(castFrom, castTo, Color.Green, Color.Green, false); } if (MyPhysics.CastRay(castFrom, castTo, out position, out normal, raycastFilterLayer, true)) { gotHit = true; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) { VRageRender.MyRenderProxy.DebugDrawSphere(position, 0.02f, Color.Green, 1, false); VRageRender.MyRenderProxy.DebugDrawText3D(position, "RayCast hit", Color.Green, 1, false); } // this is hack, if RayCast returns a hit above the graphics cast, take this one if (Vector3.Dot(position, up) > Vector3.Dot(hit.Position, up)) { hit.Position = position; hit.Normal = normal; } } } // // now we need to recalculate the hit position to center // cp.HitPosition = from - Vector3.Dot(WorldMatrix.Translation - cp.HitPosition, up) * up; // //cp.HitPosition.Interpolate3(castFrom, castTo, cp.DistanceFraction); // //cp.HitPosition -= footTranslationFromAnkle; // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // VRageRender.MyRenderProxy.DebugDrawSphere(cp.HitPosition, 0.03f, Color.Violet, 1, false); // VRageRender.MyRenderProxy.DebugDrawText3D(cp.HitPosition, "ShapeCast hit Centered", Color.Violet, 1, false); // } // // shape cast correction using the normal // //float dotProductAbs = WorldMatrix.Forward.Dot(cp.Normal); // //cp.HitPosition -= WorldMatrix.Up * (1 - dotProductAbs) * footDimension.Y; // // draw shape and ray cast hits // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // matrix.Translation = cp.HitPosition; // VRageRender.MyRenderProxy.DebugDrawOBB(Matrix.CreateScale(footDimension) * matrix, Color.White, 1, false, false); // VRageRender.MyRenderProxy.DebugDrawCapsule(Vector3.Transform(capsA, WorldMatrix.GetOrientation()) + cp.HitPosition, Vector3.Transform(capsB, WorldMatrix.GetOrientation()) + cp.HitPosition, footDimension.X, Color.Red, false); // } // // use raycast to correct position // //if (hit) // //{ // // // draw shape and ray cast hits // // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // // { // // VRageRender.MyRenderProxy.DebugDrawSphere(position, 0.02f, Color.Green, 1, false, false); // // VRageRender.MyRenderProxy.DebugDrawText3D(position, "RayCast hit", Color.Green, 1, false); // // } // // // shift the foot up for the ankle height according to the normal orientation // // //float dotProductAbs = Math.Abs( WorldMatrix.Forward.Dot(normal)); // // //{ // // // // get the difference between shape and ray cast and set the position // // // Vector3 difference = (position - cp.HitPosition) * (dotProductAbs); // // // cp.HitPosition = position - difference; // prefer shapecast when the ground is on ankle // // //} // // cp.HitPosition.Interpolate3(cp.HitPosition, position, Vector3.Dot(WorldMatrix.Up, normal)); // // //cp.Normal = normal; // //} // // where will be final foot if not ankle's shifted // if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_CHARACTER_IK_RAYCASTHITS) // { // matrix.Translation = cp.HitPosition; // VRageRender.MyRenderProxy.DebugDrawSphere(cp.HitPosition, 0.02f, Color.Red, 1, false, false); // VRageRender.MyRenderProxy.DebugDrawText3D(cp.HitPosition, "Final hit", Color.Red, 1, false); // VRageRender.MyRenderProxy.DebugDrawLine3D(cp.HitPosition, cp.HitPosition + cp.Normal, Color.YellowGreen, Color.YellowGreen, false); // VRageRender.MyRenderProxy.DebugDrawOBB(Matrix.CreateScale(footDimension) * matrix, Color.Cyan, 1, false, false); // } //} return(gotHit ? new CastHit?(hit) : null); }