public static float GetProjectileSpeed(MyGunBase gun) { if (gun == null) { Debug.Fail("Invalid argument"); return 0; } float shotSpeed = 0; if (gun.CurrentAmmoMagazineDefinition != null) { var ammoDefinition = MyDefinitionManager.Static.GetAmmoDefinition(gun.CurrentAmmoMagazineDefinition.AmmoDefinitionId); shotSpeed = ammoDefinition.DesiredSpeed; //if (ammoDefinition.AmmoType == MyAmmoType.Missile) //{ // //missiles are accelerating, shotSpeed is reached later // var mDef = (Sandbox.Definitions.MyMissileAmmoDefinition)ammoDefinition; // if (mDef.MissileInitialSpeed == 100f && mDef.MissileAcceleration == 600f && ammoDefinition.DesiredSpeed == 700f)//our missile // {//This is very good&fast correction for our missile, but not for some modded exotics with different performance // //still does not take parallel component of velocity into account, I know, but its accurate enough // shotSpeed = 800f - 238431f / (397.42f + (float)(predictedPosition - gun.GetMuzzleWorldPosition()).Length()); // } // //else {unknown missile, keep shotSpeed without correction} //} } return shotSpeed; }
public MySmallMissileLauncher() { m_gunBase = new MyGunBase(); m_soundEmitter = new MyEntity3DSoundEmitter(this, true); m_useConveyorSystem.Value = true; SyncType.Append(m_gunBase); }
public MySmallMissileLauncher() { m_gunBase = new MyGunBase(); m_soundEmitter = new MyEntity3DSoundEmitter(this); m_useConveyorSystem.Value = true; SyncType.Append(m_gunBase); }
public static float GetProjectileSpeed(MyGunBase gun) { if (gun == null) { Debug.Fail("Invalid argument"); return(0); } float shotSpeed = 0; if (gun.CurrentAmmoMagazineDefinition != null) { var ammoDefinition = MyDefinitionManager.Static.GetAmmoDefinition(gun.CurrentAmmoMagazineDefinition.AmmoDefinitionId); shotSpeed = ammoDefinition.DesiredSpeed; //if (ammoDefinition.AmmoType == MyAmmoType.Missile) //{ // //missiles are accelerating, shotSpeed is reached later // var mDef = (Sandbox.Definitions.MyMissileAmmoDefinition)ammoDefinition; // if (mDef.MissileInitialSpeed == 100f && mDef.MissileAcceleration == 600f && ammoDefinition.DesiredSpeed == 700f)//our missile // {//This is very good&fast correction for our missile, but not for some modded exotics with different performance // //still does not take parallel component of velocity into account, I know, but its accurate enough // shotSpeed = 800f - 238431f / (397.42f + (float)(predictedPosition - gun.GetMuzzleWorldPosition()).Length()); // } // //else {unknown missile, keep shotSpeed without correction} //} } return(shotSpeed); }
/// <summary> /// Algorithm to predict the position of the target /// </summary> public static bool GetPredictedTargetPosition(MyGunBase gun, MyEntity shooter, MyEntity target, out Vector3 predictedPosition, out float timeToHit, float shootDelay = 0) { Debug.Assert(target != null && target.PositionComp != null, "Null target!"); Debug.Assert(shooter != null && shooter.PositionComp != null, "Null shooter!"); if (target == null || target.PositionComp == null || shooter == null || shooter.PositionComp == null) { predictedPosition = Vector3.Zero; timeToHit = 0; return false; } Vector3 targetPosition = target.PositionComp.WorldAABB.Center; Vector3 muzzlePosition = gun.GetMuzzleWorldPosition(); Vector3 toTarget = targetPosition - muzzlePosition; Vector3 targetVelocity = Vector3.Zero; if (target.Physics != null) { targetVelocity = target.Physics.LinearVelocity; } Vector3 shooterVelocity = Vector3.Zero; if (shooter.Physics != null) { shooterVelocity = shooter.Physics.LinearVelocity; } Vector3 diffVelocity = targetVelocity - shooterVelocity; float projectileSpeed = GetProjectileSpeed(gun); float a = diffVelocity.LengthSquared() - projectileSpeed * projectileSpeed; float b = 2 * Vector3.Dot(diffVelocity, toTarget); float c = toTarget.LengthSquared(); float p = -b / (2 * a); float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a); float t1 = p - q; float t2 = p + q; float t; if (t1 > t2 && t2 > 0) { t = t2; } else { t = t1; } t = t + shootDelay; predictedPosition = targetPosition + diffVelocity * t; Vector3 bulletPath = predictedPosition - muzzlePosition; timeToHit = bulletPath.Length() / projectileSpeed; return true; }
//[TerminalValues(MySpaceTexts.SwitchText_On, MySpaceTexts.SwitchText_Off)] //[Terminal(2, MyPropertyDisplayEnum.Switch, MySpaceTexts.Terminal_UseConveyorSystem, MySpaceTexts.Blank)] //[Obfuscation(Feature = Obfuscator.NoRename, Exclude = true)] //public MyStringId UseConveyorSystemGui //{ // get { return m_useConveyorSystem ? MySpaceTexts.SwitchText_On : MySpaceTexts.SwitchText_Off; } // set // { // if (m_useConveyorSystem != (value == MySpaceTexts.SwitchText_On)) // { // m_useConveyorSystem = (value == MySpaceTexts.SwitchText_On); // OnPropertiesChanged(); // } // } //} //[TerminalValueSetter(2)] //public void RequestUseConveyorSystemChange(MyStringId newVal) //{ // MySyncConveyors.SendChangeUseConveyorSystemRequest(EntityId, newVal == MySpaceTexts.SwitchText_On); //} public override void Init(MyObjectBuilder_CubeBlock builder, MyCubeGrid cubeGrid) { SyncFlag = true; var ob = builder as MyObjectBuilder_SmallMissileLauncher; m_gunBase = new MyGunBase(); MyStringHash resourceSinkGroup; var weaponBlockDefinition = BlockDefinition as MyWeaponBlockDefinition; if (weaponBlockDefinition != null) { m_ammoInventory = new MyInventory(weaponBlockDefinition.InventoryMaxVolume, new Vector3(1.2f, 0.98f, 0.98f), MyInventoryFlags.CanReceive, this); resourceSinkGroup = weaponBlockDefinition.ResourceSinkGroup; } else { if (cubeGrid.GridSizeEnum == MyCubeSize.Small) { m_ammoInventory = new MyInventory(240.0f / 1000, new Vector3(1.2f, 0.45f, 0.45f), MyInventoryFlags.CanReceive, this); // 4 missiles } else { m_ammoInventory = new MyInventory(1140.0f / 1000, new Vector3(1.2f, 0.98f, 0.98f), MyInventoryFlags.CanReceive, this); // 19 missiles } resourceSinkGroup = MyStringHash.GetOrCompute("Defense"); } base.Init(builder, cubeGrid); m_ammoInventory.Init(ob.Inventory); m_gunBase.Init(ob.GunBase, BlockDefinition, this); m_ammoInventory.ContentsChanged += m_ammoInventory_ContentsChanged; var sinkComp = new MyResourceSinkComponent(); sinkComp.Init( resourceSinkGroup, MyEnergyConstants.MAX_REQUIRED_POWER_SHIP_GUN, () => (Enabled && IsFunctional) ? ResourceSink.MaxRequiredInput : 0.0f); ResourceSink = sinkComp; ResourceSink.IsPoweredChanged += Receiver_IsPoweredChanged; ResourceSink.Update(); AddDebugRenderComponent(new Components.MyDebugRenderComponentDrawPowerReciever(ResourceSink, this)); m_useConveyorSystem = ob.UseConveyorSystem; SlimBlock.ComponentStack.IsFunctionalChanged += ComponentStack_IsFunctionalChanged; LoadDummies(); NeedsUpdate |= MyEntityUpdateEnum.EACH_100TH_FRAME; }
public MySmallMissileLauncher() { #if XB1 // XB1_SYNC_NOREFLECTION m_useConveyorSystem = SyncType.CreateAndAddProp <bool>(); #endif // XB1 CreateTerminalControls(); #if XB1 // XB1_SYNC_NOREFLECTION m_gunBase = new MyGunBase(SyncType); #else // !XB1 m_gunBase = new MyGunBase(); #endif // !XB1 m_soundEmitter = new MyEntity3DSoundEmitter(this, true); m_useConveyorSystem.Value = true; #if !XB1 // !XB1_SYNC_NOREFLECTION SyncType.Append(m_gunBase); #endif // !XB1 }
public virtual void Init(MyEntity entity, MyLargeTurretBase turretBase) { m_entity = entity; m_turretBase = turretBase; m_gunBase = turretBase.GunBase as MyGunBase; // Check for the dummy cubes for the muzzle flash positions: if (m_entity.Model != null) { if (m_entity.Model.Dummies.ContainsKey("camera")) { CameraDummy = m_entity.Model.Dummies["camera"]; } m_gunBase.LoadDummies(m_entity.Model.Dummies); } m_entity.OnClose += m_entity_OnClose; }
//[TerminalValues(MySpaceTexts.SwitchText_On, MySpaceTexts.SwitchText_Off)] //[Terminal(2, MyPropertyDisplayEnum.Switch, MySpaceTexts.Terminal_UseConveyorSystem, MySpaceTexts.Blank)] //[Obfuscation(Feature = Obfuscator.NoRename, Exclude = true)] //public MyStringId UseConveyorSystemGui //{ // get { return m_useConveyorSystem ? MySpaceTexts.SwitchText_On : MySpaceTexts.SwitchText_Off; } // set // { // if (m_useConveyorSystem != (value == MySpaceTexts.SwitchText_On)) // { // m_useConveyorSystem = (value == MySpaceTexts.SwitchText_On); // OnPropertiesChanged(); // } // } //} //[TerminalValueSetter(2)] //public void RequestUseConveyorSystemChange(MyStringId newVal) //{ // MySyncConveyors.SendChangeUseConveyorSystemRequest(EntityId, newVal == MySpaceTexts.SwitchText_On); //} public override void Init(MyObjectBuilder_CubeBlock builder, MyCubeGrid cubeGrid) { SyncFlag = true; var ob = builder as MyObjectBuilder_SmallMissileLauncher; m_gunBase = new MyGunBase(); var weaponBlockDefinition = BlockDefinition as MyWeaponBlockDefinition; if (weaponBlockDefinition != null) { m_ammoInventory = new MyInventory(weaponBlockDefinition.InventoryMaxVolume, new Vector3(1.2f, 0.98f, 0.98f), MyInventoryFlags.CanReceive, this); } else { if (cubeGrid.GridSizeEnum == MyCubeSize.Small) m_ammoInventory = new MyInventory(240.0f / 1000, new Vector3(1.2f, 0.45f, 0.45f), MyInventoryFlags.CanReceive, this); // 4 missiles else m_ammoInventory = new MyInventory(1140.0f / 1000, new Vector3(1.2f, 0.98f, 0.98f), MyInventoryFlags.CanReceive, this); // 19 missiles } base.Init(builder, cubeGrid); m_ammoInventory.Init(ob.Inventory); m_gunBase.Init(ob.GunBase, BlockDefinition, this); m_ammoInventory.ContentsChanged += m_ammoInventory_ContentsChanged; PowerReceiver = new MyPowerReceiver( MyConsumerGroupEnum.Defense, false, MyEnergyConstants.MAX_REQUIRED_POWER_SHIP_GUN, () => (Enabled && IsFunctional) ? PowerReceiver.MaxRequiredInput : 0.0f); PowerReceiver.IsPoweredChanged += Receiver_IsPoweredChanged; PowerReceiver.Update(); AddDebugRenderComponent(new Components.MyDebugRenderComponentDrawPowerReciever(PowerReceiver, this)); m_useConveyorSystem = ob.UseConveyorSystem; SlimBlock.ComponentStack.IsFunctionalChanged += ComponentStack_IsFunctionalChanged; LoadDummies(); NeedsUpdate |= MyEntityUpdateEnum.EACH_100TH_FRAME; }
public MySmallMissileLauncher() { #if XB1 // XB1_SYNC_NOREFLECTION m_useConveyorSystem = SyncType.CreateAndAddProp<bool>(); #endif // XB1 CreateTerminalControls(); #if XB1 // XB1_SYNC_NOREFLECTION m_gunBase = new MyGunBase(SyncType); #else // !XB1 m_gunBase = new MyGunBase(); #endif // !XB1 m_soundEmitter = new MyEntity3DSoundEmitter(this, true); m_useConveyorSystem.Value = true; #if !XB1 // !XB1_SYNC_NOREFLECTION SyncType.Append(m_gunBase); #endif // !XB1 }
/// <summary> /// Algorithm to predict the position of the target /// </summary> public static bool GetPredictedTargetPosition(MyGunBase gun, MyEntity shooter, MyEntity target, out Vector3 predictedPosition, out float timeToHit, float shootDelay = 0) { Debug.Assert(target != null && target.PositionComp != null, "Null target!"); Debug.Assert(shooter != null && shooter.PositionComp != null, "Null shooter!"); if (target == null || target.PositionComp == null || shooter == null || shooter.PositionComp == null) { predictedPosition = Vector3.Zero; timeToHit = 0; return(false); } Vector3 targetPosition = target.PositionComp.WorldAABB.Center; Vector3 muzzlePosition = gun.GetMuzzleWorldPosition(); Vector3 toTarget = targetPosition - muzzlePosition; Vector3 targetVelocity = Vector3.Zero; if (target.Physics != null) { targetVelocity = target.Physics.LinearVelocity; } Vector3 shooterVelocity = Vector3.Zero; if (shooter.Physics != null) { shooterVelocity = shooter.Physics.LinearVelocity; } Vector3 diffVelocity = targetVelocity - shooterVelocity; float projectileSpeed = GetProjectileSpeed(gun); float a = diffVelocity.LengthSquared() - projectileSpeed * projectileSpeed; float b = 2 * Vector3.Dot(diffVelocity, toTarget); float c = toTarget.LengthSquared(); float p = -b / (2 * a); float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a); float t1 = p - q; float t2 = p + q; float t; if (t1 > t2 && t2 > 0) { t = t2; } else { t = t1; } t = t + shootDelay; predictedPosition = targetPosition + diffVelocity * t; Vector3 bulletPath = predictedPosition - muzzlePosition; timeToHit = bulletPath.Length() / projectileSpeed; return(true); }