In this video, we're going to start adding the cubicles in as resources that are available to the patient
and the nurse.
First of all, what we need to do is to go into our world.
So g world and add in here a queue of cubicles, just the same way that we've got this queue of patients.
Now, I'm going to leave that as an initial challenge for you to do, and I'd like you to think about
the setting up of the cubicle and how the values of each cubicle that's already in the game world are
going to get into the queue in the first place because they're not like the patients that can kind of
inject themselves in there when their goals have been achieved or an action gets to a certain place.
Okay, so go away and try and do that.
So add a queue and add all the necessary bits and pieces that need to go throughout this whole G world
class in order to look after that queue.
And when we come back, I will show you how to do that and put it together.
So pause the video now and good luck.
Welcome back.
How did you go?
Well, first of all, we have to create a queue, so that should be pretty straightforward for you,
which is to copy the patients, place it in there and call it cubicles.
Okay.
We can then go ahead.
And in the world is construct that queue.
So let's just grab that and make a copy of it and we'll call that cubicles as well.
Okay.
So then we need two helpers, which is our add cubicle and remove cubicle.
So we will just copy those and put them down in here.
So we'll just rename them as add cubicle and remove cubicle and then we'll also change the queues inside
of those so that we've got the correct ones.
Cubicle and cubicle.
Right.
So now we need to actually populate that queue because these cubicles are things that exist in the game
environment.
So one way you could do it is you could write a script that you put on each cubicle.
So as a resource it has a little script, and then it says in the start method it's say something like
Gee, world cubicles, ad cubicle and then injects itself into that queue, which is fine.
That would work fine and that would be good if you wanted to add cubicles dynamically into the world.
But what we're going to do here is actually just pick up all of the cubicles that are in the world.
So we're going to do a game object array and let's just call this cubes equals game object dot find
objects with tag.
Remember that all of those cubicles are tagged with cubicle with a capital C so we can go through the
environment and pick up the ones that are already existing.
Then we can loop through them.
So for each game object see in cubes, cubicles dot in queue.
So we stick them into the queue and we're putting C into that queue.
Then after that we also need to insert a state into the world about the cubicles and whether they're
free or not, just like if a patient is waiting.
So initially we're going to say if cubes dot length.
Is greater than zero.
Then we want to put world.
Dot modify state free cubicle.
Cubes at length.
And then when that goes into the world states, it automatically gets picked up by our little updater
that's putting it into that gooey that's on the screen.
All right.
So save that and switch back into unity.
And we just want to test that it's working.
So just press play.
And because of the world is doing it itself, we're not reliant on any of our agents updating the state.
Okay.
So now you can see it says free cubicle and there's three available and therefore we can use free cubicle,
something that our patient or our nurse is looking for in order to do another action so it can be a
precondition.
So now we have this new resource in the environment.
So it's not an agent and it's not a goal or sub goal.
It's not really a state, but it's existence causes a state.
So the cubicles are causing a state of free cubicle or I guess no free cubicles, which is kind of,
I guess the opposite.
And therefore, we need another way of organizing these things that the agents need on them or available
in order to complete a task.
And that's now where the idea of an inventory comes in.
So in our GOOP folder, what we're going to do is create an inventory.
So let's go see shop and we'll call it a G inventory just to keep up with the way we've been coding
so far with the conventions of the names.
Now, the inventory itself is not a mono behavior and therefore will not have a start and an update.
So it's basically just keeping a list.
So a list of game objects, which will be our items that we can put in our inventory or backpack or
whatever you want to call it.
So let's call it items and it's going to equal a new list of game objects.
Now it's going to require three help or functions.
And let's just get rid of that, as always, put that in there.
Okay.
So it's going to have a public void add item.
And we give it a game object eye.
And it's going to add that to your items, which is quite straightforward because it's just items don't
add.
And then I the next one is going to be a public game object that it returns and it will be find.
Item with tag given the string tag of it.
Right.
So to find the item in here, we'll just loop through it.
So for each game object I in items.
If I don't tag equals tag.
Then we're just going to return it.
Return I.
Otherwise we're going to finish our full loop not having found it and will return a null so that we
know that that item is not in our inventory.
Finally, we're going to have a remove.
So we've got the ability to put it in inventory.
Now we have to get it out.
So.
Public void.
Remove.
Item.
Game object.
I.
And this is we need to, first of all, find the index to that particular item.
So index to remove equals minus one, which means we actually haven't found that item for removing for
each.
Game object.
Or in items then going to set the index to remove equals.
Plus plus to increment it.
And then if I equals the item that we pass through, which is an AI, which is a bad idea to call them
that isn't it.
Let's call this one G for game object and then let's put G down here instead.
And if that's the case, then we're going to break out with the index set for the one that actually
just matched and then we'll go.
If index to remove is greater than or equal to minus one, then we can do an item's dot remove at.
Index to remove.
Now we need to do it this way where we loop through the whole thing first and then remove it using its
index afterwards.
Because lists do not like to have things taken out of the middle of them when you're looping through
them.
So that's why we've done it like this.
Okay, so that's our G inventory, so save that.
Now that all agents are going to require access to the inventory.
Go back into your G agent CSS script.
And at the top we're going to add in a new item which will be our inventory.
So public G inventory inventory equals a new G inventory, right?
So now all of our agents, the patients and the nurses will have access to put things in the inventory
and check that things are in the inventory.
Now, the question is, when do we get hold of the cubical and put it into our inventory?
You don't want it in there all the time because the cubicles can only be owned by one patient at a time
or one sort of nurse patient pair.
What we're going to do in this particular case, and this is not the only way that you could do it,
but first of all, we're going to have the nurse before it even starts the get patient plan, and it
will become a plan.
Currently, it's only one task that we've got in there.
We're going to add a second precondition.
So we don't even want the plan to be able to start until there's also a free cubicle.
So add free cubicle into there.
Make sure your spelling is correct, exactly the same spelling as you end up seeing up here when the
cubicles are added to the world state.
So now we've got this condition that we know there's a free cubicle in the world when the patient is
actually running.
Now the agent has an inventory, then the actions can get hold of that inventory from the agent.
But you'd have to do a get component call to get hold of it.
So what I want to do in this G action class is actually just grab hold of it in here as well so that
we can refer to it without having to write such long code or go to the optimized version of running
get component every time we need to.
So it's G inventory inventory in our actions.
And that's just going to point back to the agent that has it.
So up in here, when we're constructing our action, we're going to add into there.
Actually, I'm not doing it in the constructor, I'm doing it in the awake and in here we'll have inventory
equals this dot get component.
Which will be our agent.
DOT inventory.
Okay.
So that's going to make it a lot easier to work with and go to get patient.
So open that up.
And the first thing we're going to do is get hold of a resource.
And I've actually already started this code.
You can see it there.
The resource is going to be whatever you want to put into your inventory.
And in this case, in get patient, it happens to be the cubicle.
So we're going to get the cubicle after the target has either succeeded or fail because if we don't
get the target, we don't need a cubicle.
So let's go down here and add in resource equals g world dot instance dot remove cubicle and that will
give our resource a pointer to the cubicle that's first in that queue.
Now we also want to test if it's null or not.
So first of all, we will say if resource does not equal null, then we're going to add it to the nurses
inventory.
So inventory dot add item.
Resource.
And if it's null, if resource equals null.
Which I guess could be an L statement, couldn't.
It makes more sense, because if it's not null, it's going to be null.
Okay, so let's just get rid of that else.
If it happens to be null in this case, then g world.
Dot instance, dot add patient.
Target.
So what we're doing here is if we can't get hold of the cubicle, we're also going to release the patient
because we don't need the patient anymore and the whole pre perform is actually going to fail.
So we will also set target here to equal now and then we're going to return a false.
Now, if we get beyond this else and we're down here, it means that we are, in fact, have a true
state.
We had a free cubicle, we took away a cubicle.
So we need to affect the world state as well.
So.
G world.
Dot instance.
Dot get world.
Dot modify state.
And in here we'll be free cubical and we're going to do modifier of minus one.
So what's that going to do?
Well, it's going to reduce the count that's on that world condition by one.
Now, remember, back in Modify State in this particular example, we've got it so that if it gets to
zero, it actually removes the state completely out of the environment.
So therefore, when you run out of cubicles, there won't be any cubicles sitting in the state because
we're taking them away as we pick them up here.
Now, what's going to be on the post perform?
Well, if we've got through and we've successfully done the action, then on the Post perform, we want
to take away a waiting patient.
So G world.
Taught instance don't get world.
The Modify State and in this case its waiting.
And minus one.
And then we're also going to say if we have a target, which in this case is our agent that we've headed
to in the waiting room, then target dot get.
Component.
G agent.
Dot inventory dot add item.
Resource.
So we're adding the cubicle to the agent, the patient's inventory, so the nurse finds the cubicle.
And then if it finds if the nurse finds the patient, then the nurse gives the patient access to the
cubicle.
So now they both have the same cubicle in their inventory, which means that we can now go ahead and
create the actions where both of our agents head over to that cubicle and we'll come back and do that
in the next video.