All right.
Welcome back.
So we created a pretty cool algorithm.
Whenever we're shocking something we're getting the five closest enemies to that thing.
We're shocking.
As long as we hit an enemy.
Right.
And here in electrocute, we are going to want to show some electric beams connected to those additional
targets.
So if I go over here and shock.
I want to see a beam connected to the closest five targets.
Now we had a debug sphere here.
I'm just hitting control Z to undo that.
So I can see as soon as I release my mouse button we get those five.
Now that's because I put this in prepare to end ability.
But really though, this actually belongs not in prepare to end ability.
I'm going to control X to cut that and put this in spawn electric beam right after we've added the gameplay
cue to the first actor.
Right.
And this stuff here, I don't need this anymore.
I'm going to delete that and Ctrl V here we're going to store additional targets in spawn electric beam
after we've added our first gameplay cue.
And then we'll get these spheres right away.
Excellent.
So we get the first five or the closest five to the enemy.
So how are we going to spawn beams from that enemy to those additional targets?
Let's talk about that.
Well, first I'm going to remove the debug sphere.
And for each of our additional targets that we get, I'd like to make a function to handle adding that
shock loop queue to those enemies.
So I'm going to make a function.
And I'm going to call this ad shock loop Q to additional target, and it's going to just take an actor.
So we'll give it an input.
And we'll call this target actor.
Or we can call it actually additional target.
And it's going to be an actor.
So an actor object reference.
Okay.
What's it going to do?
First thing I'm going to promote additional target to a local variable.
We'll call it Target Actor.
And I'm going to make gameplay parameters because we're going to add a gameplay queue to it.
So we're going to do make gameplay queue parameters.
And we're going to apply a gameplay cue.
But before we go and do that, we need to keep track of all the actors we're applying a gameplay cue
to, and we need to be able to identify which one is which and which one has which cue.
So we need to associate these two together whenever we need to link an arbitrary number of pairs together.
What's the data structure that comes to your mind?
Just say it out loud.
Well, what I think is a map.
I'd like a map that maps one of these to the other.
We could map the actor to its parameters.
So I'm going to make a new variable.
And this is not going to be a local variable, because we have to use this later on in the ability.
So I'm going to add a variable and it's going to be called additional.
Actors to params.
Now I'll set its type to actor first.
Actor object reference.
But then I'm going to come over to its variable type and change it to a map.
And if I change it to a map, I need to choose its key and value.
By default it sets the value to integer.
But I'm going to make this a gameplay cue.
Parameters.
So now we have a map of actors to gameplay parameters, and as soon as I make these params, I'm going
to take my additional actors to q params and call add on it.
And I'm going to add the target actor this right.
So I made that a variable that's going to be the key.
And our queue params is going to be the value.
Now we need to set some of these Q params and the target itself.
The target actor is going to be the source object.
So not just mouse hit actor this time.
Now we have target actor.
And for the location it's going to be the target actor's location.
So get actor location on that.
We'll hook that into the location.
And what about the target attach component?
Well, before it was the weapon, right?
It was the tip socket on the staff.
But now we're connecting these electric beams from the mouse hit actor to each target.
It's going to star out.
So we're going to use the mouse hit actor for the attach target.
And from the mouse hit actor we're just going to get its root component.
That'll be its capsule.
And that's going to be the target attach component.
We can collapse that.
Like so.
And now we have a map keeping track of each of our additional targets and mapping it to the gameplay
parameters.
This will make it easy to remove those shock loop gameplay cue notifies later, and now all we need
to do is add a gameplay cue on an actor.
So I'm going to take that target actor.
And call add gameplay cue on actor, and we'll hook this up and we'll specify the shock loop cue.
And for the parameters that's going to be these params we just made.
Now this is great because we're doing this for all of those additional targets.
But now we also have a map mapping actor to params, which allows us to remove those params.
So we can go to prepare to end ability here.
And if that first target implements the combat interface, that is when we need to go through our map.
If it does not, then we didn't hit anything except for maybe a wall or the floor.
So that's this case.
We don't care about that, but in this case we do.
And we're going to need to loop over our map.
Now, the thing about maps and blueprints is we can't loop over them.
We can't say for each like we can do in C plus plus.
Unfortunately, blueprint still has a few limitations in that regard.
So for that reason, we can't really loop through the map, but we do have an array.
If we go back to spawn electric beam, when we store additional targets here, we can promote that to
an array variable.
We can drag off promote a variable, and we have our additional targets.
We'll just call it additional targets there.
And we can store that.
No problem.
And after we loop through each of the actors in additional targets and we call this function, we just
made add shock loop to additional target, we'll call it.
But since we stored additional targets, now we can loop through that.
So we can get additional targets.
And we can do a for each loop.
We don't need to try to loop over the map.
We can't do that.
But now we can remove the shock loop Q so we can take the additional target.
We can then get our map.
And we can call on the map find.
And we can pass in that target.
So that's the array element.
So we can try to find this key value pair searching for the key that is this actor.
And if we find it.
So we'll have the branch on the loop body.
We'll remove a gameplay cue from that actor.
So we'll take that array element and call remove gameplay cue on actor.
Hook that into true.
And we'll use the shock loop gameplay cue, and the parameters will be the parameters we found in our
find note here.
Now this could be a function, and if I collapse it to a function, I think I'm going to get two inputs
for that actor.
Let's see.
Yeah, we got two actors.
But those are both the same one, aren't they?
It's the array element.
So I'm going to hold control and click and drag off of this and add a root node and hook that in.
And that way I can collapse this to a function with only one input.
And this will be called remove shock loop queue from additional target.
And this function is going to look a little messy.
What we can do to clean it up is take the input pin and we can call it additional target.
And we can promote it to a local variable.
And then use the local variable.
We're going to call this new local variable target.
And we'll use that here.
Hook that up.
Get rid of that reroute node and we'll hook up target here.
Just to try to make this pretty.
So additional target promoted to local variable.
We take additional actors to q params.
Try to find that target in it, and if we find it, we remove gameplay q with shock loop and these parameters
from the target.
So here in prepare to end, we loop through additional targets and call that.
Now the last thing to do is use our ad hoc loop queue to additional target here in spawn electric beam
as we're looping over our additional targets.
So we're going to call Add Shock loop to additional target passing in the array element in for the additional
target.
Now with that.
We're adding a gameplay cue.
We're storing its cue parameters in a map, mapping that actor to the cue parameters, and then in prepare
to End, we're looping over additional targets and removing those cue parameters from that target.
Let's see how this works.
Look at that.
Oh.
That's beautiful.
And the cool thing is, if one of these is in the way, we'll hit that one.
See.
Some nice algorithm work there.
Now check this out.
I found a bug.
I hit the floor over here, and my sphere.
Trace, hit this goblin here.
Now, because of that, my initial trace actually hit something that's not a combat interface.
But my sphere trace ended up hitting this goblin here, and we ended up doing our algorithm.
And because of that, we never removed those gameplay cues.
So that's something we need to take into account.
So how does that happen?
First of all, we'll go to spawn electric beam.
And we trace our first target.
And by the time we get to does implement interface.
This is where we know at this point if mouse hit actor is an enemy or not.
But here's the thing.
By this point, we should know if there was a goblin in the way because we need to update that goblin
to the new mouse hit actor.
We have to do that first.
Now we should be updating mouse hit actor here if our sphere trace hit it.
So let's just see.
If we miss.
Okay, so I know by this point if I hit the floor that this check.
Is going to return a false.
The floor does not implement the interface, right?
So if we hit false and we set our target to the self the avatar actor.
We add the looping queue to that.
We don't want to store additional targets in that case.
So here we should actually check that boolean.
Right.
We should have a branch that checks this boolean.
First target implements interface.
If it doesn't we don't need to do this whole additional targets thing.
So let's give that a try.
Yeah.
So if we didn't check that, let's just hook false in there too.
Then we're checking within an 850.
Unit radius, right?
But if we check first, if the first target implements the combat interface, then that won't happen.
It's only if we actually hit an enemy.
Awesome.
Wow, this looks really cool, doesn't it?
And if we tie the number of beams to the ability level, then that gives us an incentive to level it
up.
Awesome.
So now we have the visual side of things looking pretty good.
We can also check on.
The client to make sure things work there.
So on the client.
Looks like things are working and consistent.
And on the server.
Things look good.
Perfect.
All right.
Excellent job.
This ability is starting to look a lot better, and we now need to start thinking about damage.
We'll do that in the videos to come.
Excellent job.
I'll see you in the next video.