NPCs reloading weapons

Started by MightyMonte88, December 15, 2020, 04:52:27 PM

MightyMonte88

Is there a way i can make NPCs reload a weapon but not need actual ammunition in their inventory? Right my NPCs are setup to just continuous fire and that is fine, but i would be nice to make them somewhat more balanced by having reload delays at least.  Below is a snippet of an crossbow i defined for use by an NPC


namespace AtomicTorch.CBND.CoreMod.Items.Weapons.MobWeapons
{
    using System.Collections.Generic;
    using AtomicTorch.CBND.CoreMod.Items.Ammo;
    using AtomicTorch.CBND.CoreMod.Systems.Weapons;
    using AtomicTorch.CBND.GameApi.Data.Weapons;
    using AtomicTorch.CBND.GameApi.Data.World;
    using AtomicTorch.CBND.CoreMod.SoundPresets;
    using AtomicTorch.CBND.GameApi.Data.Characters;
    using AtomicTorch.GameEngine.Common.Helpers;

    public class ItemWeaponMobCrossbow : ProtoItemMobWeaponArmed
    {
        public override string Name => "Crossbow";
        public override double DamageApplyDelay => 0.2;
        public override double AmmoReloadDuration => 2.75; // lower
        public override double CharacterAnimationAimingRecoilDuration => 0.6;
        public override double CharacterAnimationAimingRecoilPower => 0.75;
        public override double FireAnimationDuration => 0.6;
        public override double FireInterval => 4;
        public override string CharacterAnimationAimingName => "WeaponPistolAiming";
        public override string CharacterAnimationAimingRecoilName => "WeaponPistolShooting";
        public override void SharedOnHit(
            WeaponFinalCache weaponCache,
            IWorldObject damagedObject,
            double damage,
            WeaponHitData hitData,
            out bool isDamageStop)
        {
            base.SharedOnHit(weaponCache,
                             damagedObject,
                             damage,
                             hitData,
                             out isDamageStop);
        }
        public override double SharedUpdateAndGetFirePatternCurrentSpreadAngleDeg(WeaponState state)
        {
            // angle variation within 30 degrees
            return 25 * (RandomHelper.NextDouble() - 0.5);
        }
        protected override WeaponFirePatternPreset PrepareFirePatternPreset()
        {
            return new WeaponFirePatternPreset(
                initialSequence: new[] { 0.0, 0.4, -0.4 },
                cycledSequence: new[] { 0.5, -0.3, 0.3, -0.5, 0.0 });
        }

        protected override void PrepareMuzzleFlashDescription(MuzzleFlashDescription description)
        {
            description.Set(MuzzleFlashPresets.None);
        }

        protected override void PrepareProtoWeaponRanged(
            out IEnumerable<IProtoItemAmmo> compatibleAmmoProtos,
            ref DamageDescription overrideDamageDescription)
        {
            compatibleAmmoProtos = null;

            var damageDistribution = new DamageDistribution()
                                     .Set(DamageType.Impact, 1);

            overrideDamageDescription = new DamageDescription(
                damageValue: 17,
                armorPiercingCoef: 0.1,
                finalDamageMultiplier: 1.5,
                rangeMax: 7,
                damageDistribution: damageDistribution);
        }

        protected override ReadOnlySoundPreset<WeaponSound> PrepareSoundPresetWeapon()
        {
            return WeaponsSoundPresets.WeaponRangedBow;
        }
        protected override void ServerOnSpecialEffect(ICharacter damagedCharacter, double damage)
        {
            ServerWeaponSpecialEffectsHelper.OnFirearmHit(damagedCharacter, damage);
        }
        protected override WeaponFireTracePreset PrepareFireTracePreset()
        {
            return WeaponFireTracePresets.Arrow;
        }
    }
}

ai_enabled

Hello!

If you swap "WeaponFireTracePresets.Arrow" to any other preset, does it work? I guess it will not as there is no difference. My guess is that there is an issue with the class itself and comparing it to another NPC weapon class that works properly will help to locate the issue.

Regarding the reloadingΓÇöunfortunately, it's not possible to implement easily.

Regards!

MightyMonte88

Hey AI_Enabled, i tried to edit this post before you got here lol, i think i made a mistake between compiling and running the editor that time because now it works haha, im sorry for the confusion. There is one other odd problem i seem to be running into, i am trying to setup an NPC to use a melee weapon, but no matter what i do, the not attacking state of the weapon is invisible on the NPC, the weapon can only be seen when the NPC is attacking haha, not sure what im doing wrong but i'll supply code snippets if you need, thanks again for all the help  :)

ai_enabled

The item-in-hands visibility is determined by the Spine animation track. It can dynamically show/hide slots and the game cannot override this behavior as it's simply executing the animation tracks and can only override the slot attachments (sprites attached to slots). If you think the animation is fine and the issue is with the scripts, you need to check whether the attachment sprite is properly set. When the weapon is selected, the Spine skeleton is reset and the weapon's method ClientSetupSkeleton. The attachment sprite could be also modified any time later when necessary (e.g. crossbow switches its sprite depending on its "IsReady" state). Search in our code calls of method ClientSetupItemInHand for some examples.