/// <summary> /// Called before update loop begins /// </summary> public virtual void Start() { WeaponDefinition = CubeBlock.BlockDefinition.Id; State = new NetSync <WeaponState>(ControlLayer, TransferType.Both, WeaponState.None); State.ValueChanged += StateChanged; Reloading = new NetSync <bool>(ControlLayer, TransferType.ServerToClient, false); DeviationIndex = new NetSync <sbyte>(ControlLayer, TransferType.ServerToClient, (sbyte)MyRandom.Instance.Next(0, sbyte.MaxValue)); InventoryComponent.GetOrAddComponent(CubeBlock.CubeGrid); Inventory = CubeBlock.GetInventory(); }
public static InventoryComponent GetOrAddComponent(MyCubeGrid grid) { InventoryComponent gggc = grid.Components.Get <InventoryComponent>(); if (gggc == null) { gggc = new InventoryComponent(); gggc.Init(grid); grid.Components.Add(gggc); } return(gggc); }
public static void Fill(MyCubeBlock block, MyDefinitionId itemId) { if (!block.HasInventory) { return; } InventoryComponent comp = block.CubeGrid.Components.Get <InventoryComponent>(); if (comp == null) { return; } comp.Fill(block.GetInventory(0), itemId); }
/// <summary> /// First call in the update loop /// Used to update the firing state of this weapon /// </summary> public virtual void Update() { // stop looping if not shooting if (!IsShooting) { //if (!IsAnimated) //{ // ControlLayer.NeedsUpdate = VRage.ModAPI.MyEntityUpdateEnum.NONE; //} return; } byte notify = 0x0; DateTime currentTime = DateTime.UtcNow; double timeSinceLastShot = (currentTime - LastShootTime).TotalMilliseconds; double timeSinceLastAmmoFeed = (currentTime - LastAmmoFeed).TotalMilliseconds; if (timeSinceLastAmmoFeed > AmmoFeedInterval) { if ((Inventory.CurrentVolume.RawValue / Inventory.MaxVolume.RawValue) < InventoryFillFactorMin) { InventoryComponent.Fill(CubeBlock, gun.GunBase.CurrentAmmoMagazineId); } } //if (!MyAPIGateway.Utilities.IsDedicated && MyAPIGateway.Session != null) //{ // MyAPIGateway.Utilities.ShowNotification($"ShootTime: {timeSinceLastShot.ToString("n0")}ms - {State.Value} - {IsShooting} - {IsReloading} - {(timeSinceLastShot * (AmmoData.RateOfFire * Tools.MinutesToMilliseconds)).ToString("n2")} {CurrentShotInBurst}/{AmmoData.ShotsInBurst}", 1); //} // Stops if weapons are reloading if (IsReloading) { if (timeSinceLastShot < ReloadTime) { return; } Reloading.Value = false; //State.Value &= ~WeaponState.Reloading; } // Stops if weapons are not ready to fire this frame if (timeSinceLastShot * (AmmoData.RateOfFire * Tools.MinutesToMilliseconds) < 1f) { return; } // Stops if weapons are not working/functional if (!Block.IsWorking) { if (!Block.IsFunctional) { notify |= 0x1; } else { notify |= 0x2; } } else { bool enoughAmmo = gun.GunBase.HasEnoughAmmunition(); if (!enoughAmmo) { StartNoAmmoSound(); notify |= 0x4; } else if (MySessionComponentSafeZones.IsActionAllowed(Block.GetPosition(), Tools.CastProhibit(MySessionComponentSafeZones.AllowedActions, 2))) { // Fixed guns do not update unless the mouse is pressed. // This updates the position when terminal fire is active. if (IsFixedGun) { MyEntitySubpart subpart; if (CubeBlock.Subparts.TryGetValue("Barrel", out subpart)) { gun.GunBase.WorldMatrix = subpart.PositionComp.WorldMatrixRef; } } // NOTE: RateOfFire is limited to 3600 rounds per seconds using this method MatrixD muzzleMatrix = gun.GunBase.GetMuzzleWorldMatrix(); Vector3 direction = muzzleMatrix.Forward; Vector3D origin = muzzleMatrix.Translation; string ammoId = gun.GunBase.CurrentAmmoDefinition.Id.SubtypeId.String; AmmoDefinition ammo = Settings.AmmoDefinitionLookup[ammoId]; // calculate deviation sbyte index = DeviationIndex.Value; MatrixD positionMatrix = Matrix.CreateWorld(origin, Tools.ApplyDeviation(direction, DeviateShotAngle, ref index), muzzleMatrix.Up); DeviationIndex.SetValue(index, SyncType.None); // spawn projectile Core.Static.Spawn(positionMatrix.Translation, positionMatrix.Forward, Block.CubeGrid.Physics.LinearVelocity, Block.EntityId, ammo); //Projectile bullet = new Projectile(CubeBlock.EntityId, positionMatrix.Translation, positionMatrix.Forward, Block.CubeGrid.Physics.LinearVelocity, ammoId); //Core.SpawnProjectile(bullet); gun.GunBase.ConsumeAmmo(); //apply recoil if (ammo.BackkickForce > 0) { //CubeBlock.Physics.AddForce(MyPhysicsForceType.APPLY_WORLD_IMPULSE_AND_WORLD_ANGULAR_IMPULSE, -direction * ammo.BackkickForce, CubeBlock.WorldMatrix.Translation, Vector3.Zero); //Core.PhysicsRequests.Enqueue(new PhysicsDefinition { // Target = CubeBlock, // Force = -direction * ammo.BackkickForce, // Position = CubeBlock.WorldMatrix.Translation //}); } // create sound StartShootSound(); //MakeSecondaryShotSound(); // create muzzle flash if (!MyAPIGateway.Utilities.IsDedicated && Settings.Static.DrawMuzzleFlash) { MatrixD matrix = MatrixD.CreateFromDir(direction); matrix.Translation = origin; bool foundParticle = MyParticlesManager.TryCreateParticleEffect(MuzzleFlashSpriteName, ref matrix, ref origin, uint.MaxValue, out muzzleFlash); if (foundParticle) { MuzzleFlashActive = true; MuzzleFlashCurrentTime = 0; muzzleFlash.Play(); } } CurrentShotInBurst++; if (AmmoData.ShotsInBurst == 0) { CurrentShotInBurst = 0; } else if (CurrentShotInBurst == AmmoData.ShotsInBurst) { notify |= 0x8; CurrentShotInBurst = 0; Reloading.Value = true; //State.Value |= WeaponState.Reloading; DeviationIndex.Push(); } if (IsTerminalShootOnce) { State.SetValue(State.Value & ~WeaponState.TerminalShootOnce); } LastShootTime = currentTime; } } if (Notify != notify) { Core.NotifyNextFrame(Block.CubeGrid.EntityId); Notify = notify; } }