Arrow Quiver

That should be fairly simple, similar to how it’s handled in EquipSlotUI

I would probably give my NPC a copy of the WeaponConfig with no AmmunitionItem in the definition…

Pardon me for tonight Brian, as I have to go for an emergency. Can we continue this tomorrow?

I’m out of time anyways… the QuiverSlotUI’s button code is your homework anyways.

Alright that’s fair. I’ll update you tomorrow :slight_smile:

Hi Brian, alright so I got the button to work after trying the ‘TryHandleRightClick()’ function (and linking the buttons up), and believe me, I am really happy about it… BUT, there’s a small problem. And the problem is, the amount that returns to the inventory is NOT the same amount that goes to the quiver, and I’m guessing it has to do with the line regarding the ‘RemoveItem()’ below:

public void TryHandleRightClick(Inventory inventory) {

            if (GetItem() is AmmunitionItem ammunitionItem) {

                AmmunitionItem equippedAmmunition = quiver.GetItem();

                if (inventory.HasSpaceFor(equippedAmmunition)) {

                    inventory.AddToFirstEmptySlot(equippedAmmunition, 1);
                    // THE AMOUNT GOING IN IS PROBABLY THE PROBLEM REGARDING WHY THE RETURN IS JUST 1, NOT ALL THE AMMO THAT WENT IN:
                    quiver.RemoveAmmunition(quiver.GetAmount());

                }

            }

        }

Please take a look and let me know what input can go into ‘quiver.RemoveAmmunition()’ (I’m guessing that’s the origin of the problem)

As for my enemy NPCs running out of ammo, I think I will create a copy of my ‘WeaponConfig’ and assign a value to them, or give them a very big amount of ammo that the value just doesn’t matter (which one should I go for…?)

Look at how many you are sending to Inventory (hint: It’s just 1)
Look at how many you are removing from quiver (hint: It’s all of them)

uhh, that’s the point… right? This line isn’t working for some reason tho (I tried placing ‘quiver.GetAmount()’ as the second argument for ‘AddToFirstEmptySlot()’ as well, but that failed… Now it doesn’t even get the arrows out of the quiver to begin with)

And there’s also a brand new bug I just noticed… the Equipment no longer get dropped on death for some reason (again)

I just pasted your code into my QuiverSlotUI, replacing 1 with quiver.GetAmount() (you also could have just used GetNumber(), which calls quiver.GetAmount(), and it’s working flawlessly.

Then something for me went so wrong… because it’s just flat out not going to pull the entire quiver out to the inventory at the exact same number. What else can I debug to fix this? (P.S: Sorry for the delay, I’m coding between classes)

Edit: Apparently my ‘TryHandleRightClick()’ disappeared from my ‘QuiverSlotUI’ OnClick() function call in the inspector, for god knows what reason, although it was set to public in-code

Edit 2: I FIXED IT… Apparently I had a second parameter, ‘int number’ that I placed earlier that got this function to be deleted, because the parameter was unused. So today, I learned that ‘public void’ functions won’t be called in a button ‘OnClick()’ event if they have unused parameters… Got it!

Now my last step would be to duplicate my ‘WeaponConfig’ script without the conditions of the enemy. Speaking of that, why don’t we add an ‘isEnemy’ boolean instead, and deactivate that in the player, and keep it activated in the enemy, so that we don’t check for arrows for the enemy?

If we can add one last functionality though, it would be dropping arrows when the enemy is hit. So for example, if I fire an arrow at you, and it hits you, we instantiate it at a place around the enemy, so the player can re-collect it later down the line after the fight, saving his own resources (I think this one should be easy though, but I’d love to hear your approach towards it as well)

Ahh… there’s a game building error that goes as follows: “Cannot build player while editor is importing assets or compiling scripts”… Please help, my game won’t compile now

If it helps in anyway, I recently moved my files around a bit. Not sure if that’s useful, but figured I’d say it anyway

Edit: The Chaos was caused by an Experimental library by Unity that I accidentally imported in my ‘QuiverSlotUI.cs’ (I don’t even know how that happened, but it did…), we fixed it :slight_smile:

But I still have two major issues (1 and 2), and two requests (3 and 4):

  1. The equipment drop is not working as expected anymore, for god knows what reason (there’s no errors, no warnings… nothing. It just stopped working, and all debugger locations so far are failing, and I have absolutely no idea why)… Edit: it works, but randomly. In other words, it sometimes checks for 4 items, and sometimes it just flat out doesn’t even consider the Equipment Slots for some reason, I’m re-checking the drop algorithm for that

Edit 2: I fixed it, by flipping the < to > in the ‘if’ statement in the foreach loop of RandomDropper.DropIDroppableItems(); - now it looks like this:

if (keep >= numberToKeep - 1) continue; // if you have more than 3 items kept, just break out of this loop to the rest of the function
  1. I still can’t find a way to get the NPC to have arrows, as his script and the player script are the same (Please help. I tried fixing this by introducing new variables and a boolean for the new ‘CheckForProjectileAndSufficientAmmo()’ function in ‘Fighter.cs’, but that drastically failed

  2. If we have the time, we can investigate instantiating arrows around the enemy, indicating arrows falling on the ground (I’ll take a wild guess and say this has something to do with the “Hit()” function in ‘Health.cs’)

  3. make the arrows droppable on death as well (from the player… from the enemy, I can tune the Drop Library for that). For this, my guess is a simple quiver check might do the trick

This isn’t breaking out of the loop. It’s stopping this iteration and moving on to the next one. You want

if (keep >= numberToKeep - 1) break; // if you have more than 3 items kept, just break out of this loop to the rest of the function

Somehow… both work well :stuck_out_tongue_winking_eye: - I’ll stick with the break though (P.S: I’ll edit the rest of the issues I have in the previous comment when I reach new heights)

OK the ‘break’ messed the whole thing up… Somehow, the ‘continue’ does the trick, so I’ll use that instead

That simply isn’t how GetComponents<T>() and IEnumerables work…

        public void DropIDroppableItems()
        {
            int keep = -1;
            //Items are sorted from MOST valuable to LEAST valuable
            foreach (DroppableItem droppableItem in GetAllDroppableItems().OrderByDescending(d=>d.number*d.relativeValue))
            {
                keep++; 
                if (keep < numberToKeep) continue;
                droppableItem.dropItemCallback?.Invoke(); //Remove the items
                DropItem(droppableItem.item, droppableItem.number);
            }
            TriggerDroppableUpdates();
        }

It’s definitely POSITIVELY supposed to be if (keep < numberToKeep) continue;
Here’s the logic:
You want to keep your most valuable items across Equipment and Inventory, represented by numberToKeep. So suppose your number to keep is 3…
1st most valuable Item:

                keep++;  //Keep = 0
                if (keep < numberToKeep) continue; // 0 < 3, continue keeps item

2nd most valuable item

                keep++;  //Keep = 1
                if (keep < numberToKeep) continue; //1 < 3, continue keeps item

3rd most valuable item

                keep++; //Keep = 2
                if (keep < numberToKeep) continue; //2 < 3, continue keeps item

4th most valuable item

                keep++; //Keep = 3
                if (keep < numberToKeep) continue; //3 !<3, do not continue, drop item

5th most valuable item

                keep++; //keep = 4
                if (keep < numberToKeep) continue; //4 !< 3, do not continue, drop item

and so on…
What’s likely happening is that the items in your Equipment are worth the most…

Let’s test this with a Debug.Log, note that the debug will not show where the item came from, because DropIDropppableItems() doesn’t care where they came from.

            foreach (DroppableItem droppableItem in GetAllDroppableItems().OrderByDescending(d=>d.number*d.relativeValue))
            {
                keep++; 
                Debug.Log($"Item #{keep} = {droppableItem.item.GetDisplayName()}, qty {droppableItem.number}, value = {droppableItem.item.GetPrice * droppableItem.number} will keep = {keep<numberToKeep}");
                if(keep < numberToKeep) continue;

There are two ways to approach this. The most sensible one (the approach taken by major game houses like Blizzard!) is to simply not have enemies worry about ammunition. (Actually WoW decided after their 2nd expansion that ammunition was causing players to avoid running dungeons where access to more ammo was limited and eliminated ammo altogether). In this case, the answer to accomplishing this is simple. Create TWO versions of the ranged WeaponConfigs. One for players with the AmmunitionItem filled in, and one for Enemies with the AmmunitionItem left as null.

Beyond that, you could create a SerializeFields in the Quiver component with starting ammunition/quantiy and in Awake() (NOT Start()) copy these fields (assuming the ammunition is not null) to the currentAmmunition. Then you would just set that on enemies.

Bear in mind that your players will quickly figure out how much ammo these enemies have and exploit this to their gain. Move towards enemies, back away when they shoot, rinse repeat until enemy stands there with no ammo.

It will have more to do with the projectile’s OnTriggerEntered() method. You could add a field with the AmmunitionType and use the same logic we use in RandomDropper to find a suitable location to drop a pickup.

Your Quiver would just implement the IDroppableItem interface and if the Quiver has ammo, yield return a new DroppableItem with the item, the number held, the item’s value, and a callback closure to remove the items.

Where exactly do we edit this in the ‘WeaponConfig.cs’ script? I can’t find any functions there, apart from the ‘AmmunitionItem()’ to handle arrows

I’ll get to the other two requests once the first one is done

Not WeaponConfig scripts, WeaponConfigs, as in the actual asset in the Resources folder.

Player gets one with the AmmunitionType filled in.
Enemy gets one with the AmmunityType null.

I didn’t know we had a WeaponConfig asset… Can’t find one in my folders either tbh :sweat_smile:

Wait, are we talking about creating a new WeaponConfig ScriptableObject (or whatever you call that thing that allows you to make it as an asset…)?

If so, I’d guess we’d install a new one for our NPCs

Um…

Yes, That’s what I meant by an Asset, in a Resources folder. That thing we drag into our Weapon slot.

Oh dear god I mixed an asset with a prefab… I meant I didn’t know we had a WeaponConfig PREFAB, not an asset, my bad…

Privacy & Terms