void UpdateGoals(MySmallShipBot bot) { moveTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000; lookTarget = bot.GetPosition() + MyMwcUtils.GetRandomVector3Normalized() * 1000; up = MyMwcUtils.GetRandomVector3Normalized() * 1000; shoot = MyMwcUtils.GetRandomBool(2); }
public override void UpdateBeforeSimulation() { base.UpdateBeforeSimulation(); if (m_elapsedMiliseconds > MyIlluminatingShellsConstants.MAX_LIVING_TIME + MyIlluminatingShellsConstants.DIYNG_TIME) { if (m_particleEffect != null) { m_particleEffect.Stop(); m_particleEffect = null; } // Free the light if (m_light != null) { MyLights.RemoveLight(m_light); m_light = null; } MarkForClose(); } // Update light position if (m_light != null) { // Aggro near bots if (m_light.LightOn) { if (this.WorldMatrix.Translation != m_previousPosition) { MyLine line = new MyLine(m_previousPosition, WorldMatrix.Translation); MyDangerZones.Instance.Notify(line, OwnerEntity); } } if ((m_elapsedMiliseconds > MyIlluminatingShellsConstants.MAX_LIVING_TIME) && (m_elapsedMiliseconds < MyIlluminatingShellsConstants.MAX_LIVING_TIME + MyIlluminatingShellsConstants.DIYNG_TIME)) { m_light.LightOn = MyMwcUtils.GetRandomBool(2); m_particleEffect.UserScale = m_light.LightOn ? 1.0f : 0.001f; } m_light.SetPosition(GetPosition()); m_light.Color = MyIlluminatingShellsConstants.LIGHT_COLOR; m_light.Range = MyIlluminatingShellsConstants.LIGHT_RADIUS; } }
void TrySwitchToFlyAround(MySmallShipBot bot) { Vector3?result = null; if (bot.TryGetTestPositionResult(ref result)) { if (result.HasValue) { m_flyToTarget = result.Value; m_flyAroundTimer = MyMwcUtils.GetRandomFloat(2, 3); m_strafe = MyMwcUtils.GetRandomBool(4); //Vector3.DistanceSquared(flyToTarget, bot.GetPosition()) < STRAFE_DISTANCE_SQR; m_state = StateEnum.FLYING_AROUND; } else { // Position failed, try again bool success = TrySwitchToAttackSearch(bot); Debug.Assert(success); } } }
/// <summary> /// Once per few frames, generates a flicker. /// Actually only manipulates the m_scale vector in order to simulate flicker appearance. /// </summary> private void GenerateFlicker() { // TODO simon how do I make this independent of FPS? bool startFlickerNow = MyMwcUtils.GetRandomBool(MyHologramConstants.FLICKER_FREQUENCY); if (startFlickerNow && m_flickerElapsedMilliseconds > MyHologramConstants.FLICKER_DURATION) { m_flickerElapsedMilliseconds = 0; m_flickerScale = MyMwcUtils.GetRandomVector3Normalized(); } if (m_flickerElapsedMilliseconds < MyHologramConstants.FLICKER_DURATION) { float flickerProgress = m_flickerElapsedMilliseconds / MyHologramConstants.FLICKER_DURATION; Vector3 maxFlickerScale = MyHologramConstants.FLICKER_MAX_SIZE * Vector3.One; m_scale = Vector3.Lerp(maxFlickerScale, m_flickerScale, flickerProgress); } else { m_scale = Vector3.One; } m_flickerElapsedMilliseconds += MyConstants.PHYSICS_STEP_SIZE_IN_MILLISECONDS; }
// Update position, check collisions, etc. // Return false if projectile dies/timeouts in this tick. public bool Update() { // Projectile was killed , but still not last time drawn, so we don't need to do update (we are waiting for last draw) if (m_state == MyProjectileStateEnum.KILLED) { return(true); } // Projectile was killed and last time drawn, so we can finally remove it from buffer if (m_state == MyProjectileStateEnum.KILLED_AND_DRAWN) { if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } return(false); } Vector3 position = m_position; m_position += m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS; m_velocity = m_externalVelocity * m_externalAddition + m_directionNormalized * m_speed; if (m_externalAddition < 1.0f) { m_externalAddition *= 0.5f; } // Distance timeout float trajectoryLength = Vector3.Distance(m_position, m_origin); if (trajectoryLength >= m_maxTrajectory) { if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } m_state = MyProjectileStateEnum.KILLED; return(true); } if (m_trailEffect != null) { m_trailEffect.WorldMatrix = Matrix.CreateTranslation(m_position); } m_checkIntersectionIndex++; m_checkIntersectionIndex = m_checkIntersectionIndex % CHECK_INTERSECTION_INTERVAL; //check only each n-th intersection if (m_checkIntersectionIndex != 0) { return(true); } // Calculate hit point, create decal and throw debris particles Vector3 lineEndPosition = position + CHECK_INTERSECTION_INTERVAL * (m_velocity * MyConstants.PHYSICS_STEP_SIZE_IN_SECONDS); MyLine line = new MyLine(m_positionChecked ? position : m_origin, lineEndPosition, true); m_positionChecked = true; MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("MyEntities.GetIntersectionWithLine()"); MyIntersectionResultLineTriangleEx?intersection = MyEntities.GetIntersectionWithLine(ref line, m_ignorePhysObject, null, false); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); MyEntity physObject = intersection != null ? intersection.Value.Entity : null; if (physObject != null) { while (physObject.Physics == null && physObject.Parent != null) { physObject = physObject.Parent; } } if ((intersection != null) && (physObject != null) && (physObject.Physics.CollisionLayer != MyConstants.COLLISION_LAYER_UNCOLLIDABLE) && m_ignorePhysObject != physObject) { MyIntersectionResultLineTriangleEx intersectionValue = intersection.Value; bool isPlayerShip = MySession.PlayerShip == physObject; MyMaterialType materialType = isPlayerShip ? MyMaterialType.PLAYERSHIP : physObject.Physics.MaterialType; //material properties MyMaterialTypeProperties materialProperties = MyMaterialsConstants.GetMaterialProperties(materialType); bool isProjectileGroupKilled = false; if (m_sharedGroup != null) { isProjectileGroupKilled = m_sharedGroup.Killed; m_sharedGroup.Killed = true; } if (!isProjectileGroupKilled) { // Play bullet hit cue MyAudio.AddCue3D(m_ammoProperties.IsExplosive ? materialProperties.ExpBulletHitCue : materialProperties.BulletHitCue, intersectionValue.IntersectionPointInWorldSpace, Vector3.Zero, Vector3.Zero, Vector3.Zero); } float decalAngle = MyMwcUtils.GetRandomRadian(); // If we hit the glass of a miner ship, we need to create special bullet hole decals // drawn from inside the cockpit and change phys object so rest of the code will think we hit the parent // IMPORTANT: Intersection between projectile and glass is calculated only for mining ship in which player sits. So for enemies this will be never calculated. if (intersection.Value.Entity is MyCockpitGlassEntity) { if (!isProjectileGroupKilled) { MyCockpitGlassDecalTexturesEnum bulletHoleDecalTexture; float bulletHoleDecalSize; if (MyMwcUtils.GetRandomBool(3)) { bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleOnGlass; bulletHoleDecalSize = 0.25f; } else { bulletHoleDecalTexture = MyCockpitGlassDecalTexturesEnum.BulletHoleSmallOnGlass; bulletHoleDecalSize = 0.1f; } // Place bullet hole decal on player's cockpit glass (seen from inside the ship) MyCockpitGlassDecals.Add(bulletHoleDecalTexture, bulletHoleDecalSize, decalAngle, 1.0f, ref intersectionValue, false); // Create hit particles throwed into the cockpit (it's simulation of broken glass particles) // IMPORTANT: This particles will be relative to miner ship, so we create them in object space coordinates and update them by object WorldMatrix every time we draw them //MyParticleEffects.CreateHitParticlesGlass(ref intersectionValue.IntersectionPointInObjectSpace, ref intersectionValue.NormalInWorldSpace, ref line.Direction, physObject.Parent); } } // If this was "mine", it must explode else if (physObject is MyMineBase) { m_state = MyProjectileStateEnum.KILLED; if (!IsDummy) { (physObject as MyAmmoBase).Explode(); } return(true); } // If this was missile, cannon shot, it must explode if it is not mine missile else if (physObject is MyAmmoBase) { if (((MyAmmoBase)physObject).OwnerEntity == m_ignorePhysObject) { m_state = MyProjectileStateEnum.KILLED; if (!IsDummy) { (physObject as MyAmmoBase).Explode(); } return(true); } } else if (this.OwnerEntity is MySmallShip && (MySmallShip)this.OwnerEntity == MySession.PlayerShip && physObject is MyStaticAsteroid && !physObject.IsDestructible) { if (this.m_ammoProperties.IsExplosive || (this.m_ammoProperties.AmmoType == MyAmmoType.Explosive && this.m_weapon is Weapons.MyShotGun)) { HUD.MyHud.ShowIndestructableAsteroidNotification(); } } else if (!isProjectileGroupKilled && !isPlayerShip) { // Create smoke and debris particle at the place of voxel/model hit m_ammoProperties.OnHitParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, m_weapon, OwnerEntity); MySurfaceImpactEnum surfaceImpact; if (intersectionValue.Entity is MyVoxelMap) { var voxelMap = intersectionValue.Entity as MyVoxelMap; var voxelCoord = voxelMap.GetVoxelCenterCoordinateFromMeters(ref intersectionValue.IntersectionPointInWorldSpace); var material = voxelMap.GetVoxelMaterial(ref voxelCoord); if (material == MyMwcVoxelMaterialsEnum.Indestructible_01 || material == MyMwcVoxelMaterialsEnum.Indestructible_02 || material == MyMwcVoxelMaterialsEnum.Indestructible_03 || material == MyMwcVoxelMaterialsEnum.Indestructible_04 || material == MyMwcVoxelMaterialsEnum.Indestructible_05_Craters_01) { surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE; } else { surfaceImpact = MySurfaceImpactEnum.DESTRUCTIBLE; } } else if (intersectionValue.Entity is MyStaticAsteroid) { surfaceImpact = MySurfaceImpactEnum.INDESTRUCTIBLE; } else { surfaceImpact = MySurfaceImpactEnum.METAL; } m_ammoProperties.OnHitMaterialSpecificParticles(ref intersectionValue.IntersectionPointInWorldSpace, ref intersectionValue.Triangle.InputTriangleNormal, ref line.Direction, physObject, surfaceImpact, m_weapon); } if (!(physObject is MyExplosionDebrisBase) && physObject != MySession.PlayerShip) { // Decal size depends on material. But for mining ship create smaller decal as original size looks to large on the ship. float decalSize = MyMwcUtils.GetRandomFloat(materialProperties.BulletHoleSizeMin, materialProperties.BulletHoleSizeMax); // Place bullet hole decal float randomColor = MyMwcUtils.GetRandomFloat(0.5f, 1.0f); MyDecals.Add( materialProperties.BulletHoleDecal, decalSize, decalAngle, new Vector4(randomColor, randomColor, randomColor, 1), false, ref intersectionValue, 0.0f, m_ammoProperties.DecalEmissivity, MyDecalsConstants.DECAL_OFFSET_BY_NORMAL); } if (!(physObject is MyVoxelMap) && !IsDummy) { ApplyProjectileForce(physObject, intersectionValue.IntersectionPointInWorldSpace, m_directionNormalized, isPlayerShip); } // If this object is miner ship, then shake his head little bit if (physObject is MySmallShip && !IsDummy) { MySmallShip minerShip = (MySmallShip)physObject; minerShip.IncreaseHeadShake(MyHeadShakeConstants.HEAD_SHAKE_AMOUNT_AFTER_PROJECTILE_HIT); } //Handle damage MyEntity damagedObject = intersectionValue.Entity; // not a very nice way to damage actual prefab associated with the large ship weapon (if MyPrefabLargeWeapon is reworked, it might change) if (damagedObject is MyLargeShipBarrelBase) { damagedObject = damagedObject.Parent; } if (damagedObject is MyLargeShipGunBase) { MyLargeShipGunBase physObj = damagedObject as MyLargeShipGunBase; if (physObj.PrefabParent != null) { damagedObject = physObj.PrefabParent; } } // Decrease health of stricken object if (!IsDummy) { damagedObject.DoDamage(m_ammoProperties.HealthDamage, m_ammoProperties.ShipDamage, m_ammoProperties.EMPDamage, m_ammoProperties.DamageType, m_ammoProperties.AmmoType, m_ignorePhysObject); if (MyMultiplayerGameplay.IsRunning) { var ammo = MyAmmoConstants.FindAmmo(m_ammoProperties); MyMultiplayerGameplay.Static.ProjectileHit(damagedObject, intersectionValue.IntersectionPointInWorldSpace, this.m_directionNormalized, ammo, this.OwnerEntity); } } if (m_trailEffect != null) { // stop the trail effect m_trailEffect.Stop(); m_trailEffect = null; } // Kill this projectile (set the position to intersection point, so we draw trail polyline only up to this point) m_position = intersectionValue.IntersectionPointInWorldSpace; m_state = MyProjectileStateEnum.KILLED; return(true); } return(true); }