WEBVTT

00:00.920 --> 00:02.840
Welcome to your next quest.

00:02.870 --> 00:07.460
In this quest, we are going to want to add some things to our effect context.

00:07.490 --> 00:14.270
You see in the exec calc, we've determined whether we got a successful debuff, but now we need to

00:14.270 --> 00:16.500
get that information on through.

00:16.520 --> 00:22.990
I'd like to send that info through to the attribute set and the effect context.

00:23.000 --> 00:27.560
So for your quest, I'd like you to add some variables to the effect context.

00:27.590 --> 00:32.900
We want to know whether or not it was a successful debuff by the time we hit the attribute set.

00:32.900 --> 00:40.690
So add a boolean for a successful debuff, call it b is successful debuff and add some floats as well.

00:40.700 --> 00:47.210
We need to send the debuff damage as well as the debuff duration and the debuff frequency.

00:47.240 --> 00:51.830
Now if you'd like a bonus, see if you can send the damage type as well.

00:51.830 --> 00:55.580
So add that to the effect context if you want an extra challenge.

00:56.500 --> 01:03.220
Now the damage type is going to be trickier because these variables need to be serialized.

01:03.250 --> 01:05.530
They need to be added to net serialized.

01:05.560 --> 01:06.300
Right.

01:06.310 --> 01:12.040
So that's part of your challenge, not just adding these variables, but taking care of serializing

01:12.040 --> 01:16.520
them as well as adding getters and setters for them.

01:16.540 --> 01:23.770
And if you want to take it above and beyond add functions in or a ability system library for getting

01:23.770 --> 01:24.820
and setting them.

01:24.970 --> 01:32.080
So damage type is an gameplay tag that's more complicated than serializing a boolean or a float.

01:32.110 --> 01:38.080
So if you feel like that extra challenge, add the damage type and I'll give you a hint for the damage

01:38.080 --> 01:38.350
type.

01:38.350 --> 01:41.070
If you don't want to hear that, pause the video now.

01:41.080 --> 01:43.330
But if you want the hint, here it is.

01:43.450 --> 01:47.110
Take a look at how a hit result is serialized.

01:47.230 --> 01:50.950
So pause the video and conquer this quest now.

01:54.920 --> 02:01.400
So our challenge is to add some more variables to our custom effect context class.

02:01.550 --> 02:08.000
So I'm going to close all my tabs and open aura ability types dot h, and we're going to add some more

02:08.000 --> 02:09.140
variables here.

02:09.230 --> 02:12.830
So down in the protected section, they can come in down here.

02:12.860 --> 02:24.290
I'm going to add a new boolean called B is successful debuff and it'll be set to false by default and

02:24.290 --> 02:25.700
it needs to be a boolean.

02:26.450 --> 02:29.540
Now in addition to this boolean, we need some floats.

02:29.540 --> 02:31.970
I need a float called debuff damage.

02:32.990 --> 02:35.060
It'll be zero by default.

02:35.090 --> 02:37.640
I need a float called debuff duration.

02:39.290 --> 02:48.350
That'll be zero by default and I need a float called debuff frequency that will be zero by default as

02:48.350 --> 02:49.040
well.

02:49.250 --> 02:53.540
And I'll put you property macros on every single one of these.

02:56.290 --> 02:57.820
So that's step one.

02:58.030 --> 03:00.520
If only this challenge were that easy.

03:00.550 --> 03:04.180
Step two is making sure that these are serialized.

03:04.420 --> 03:05.930
That's step two.

03:05.950 --> 03:09.100
So we can break step two down into sub steps.

03:09.130 --> 03:15.940
First, we need to look at our ability types dot cpp and see how we're serializing everything else.

03:15.970 --> 03:22.000
If we're saving, then we're flipping bits and we're kind of going in order here.

03:22.000 --> 03:23.990
The order sort of matters, right?

03:24.010 --> 03:31.120
And at the very end we're flipping bits seven and eight for B is blocked hit and B is critical hit.

03:31.150 --> 03:32.500
We're going to flip more bits.

03:32.530 --> 03:39.730
Now we need to flip a bit to represent whether or not we should serialize B is successful debuff and

03:39.730 --> 03:42.520
we should only flip it if b is successful.

03:42.520 --> 03:46.480
Debuff is true, otherwise we can save on some bandwidth.

03:46.870 --> 03:53.620
So I'm going to place an if and say if b is successful debuff, then we'll flip the next bit.

03:53.620 --> 03:55.210
So we're going to take rep bits.

03:55.240 --> 04:02.400
We're going to use a bitwise or equals and we'll use one left shift nine.

04:02.420 --> 04:06.950
So only if it's a successful debuff we'll flip that ninth bit.

04:07.340 --> 04:12.200
We can use the same optimization techniques for the debuff variables.

04:12.200 --> 04:16.030
If they're zero, there's no point in replicating.

04:16.040 --> 04:21.730
So we can flip bits ten, 11 and 12 only if these are nonzero.

04:21.740 --> 04:27.260
In fact, if they're greater than zero it doesn't make sense for debuff damage, duration or frequency

04:27.260 --> 04:28.310
to be negative.

04:28.340 --> 04:33.710
So I'm going to check if debuff and I want to go in order.

04:33.710 --> 04:38.270
Debuff damage is greater than zero.

04:39.950 --> 04:42.640
Then I'll go ahead and flip the next bit.

04:42.650 --> 04:47.060
I'll just copy this and paste it, but we're going to flip bit number ten.

04:48.100 --> 04:51.540
Next we need debuff duration and frequency.

04:51.550 --> 05:00.160
So I'm going to take the if statement copy, paste it and change this to debuff duration.

05:00.910 --> 05:03.370
And we'll flip it 11 for that.

05:03.370 --> 05:06.820
And then one more time, copy paste.

05:06.850 --> 05:09.070
This will be debuff frequency.

05:10.350 --> 05:13.050
And we'll flip the next bit, which is bit 12.

05:13.080 --> 05:16.050
So that takes care of flipping the bits.

05:16.230 --> 05:22.440
After that, we have the serialization part, the archiving into our archive.

05:22.470 --> 05:28.320
So we're going to go all the way down to after we've archived be is critical hit and we're going to

05:28.320 --> 05:29.700
archive the next one.

05:30.090 --> 05:34.110
So first we check to see if the next bit has been flipped.

05:34.110 --> 05:40.740
That's nine and then we archive B is successful debuff that one was pretty easy.

05:40.770 --> 05:44.800
Next we check to see if the 10th bit has been flipped.

05:44.820 --> 05:48.710
If so, we archive our debuff damage.

05:48.720 --> 05:50.070
We have to go in order.

05:50.070 --> 05:54.090
It doesn't have to be in the same order as the variables are declared.

05:54.090 --> 06:01.810
It has to be in the same order that we flipped the bits up here because those bits represent these variables.

06:01.830 --> 06:05.940
So it's debuff damage, duration and then frequency.

06:06.060 --> 06:09.040
So here we got debuff damage.

06:09.060 --> 06:12.580
Next we're going to check the 11th bit.

06:12.700 --> 06:17.740
So change this to an 11 and this will be debuff duration.

06:19.090 --> 06:20.980
And the frequency is last.

06:20.980 --> 06:28.060
So we're going to get the if statement, copy it, change this to the 12th bit and this will be debuff

06:28.060 --> 06:29.050
frequency.

06:30.760 --> 06:31.960
And there we go.

06:31.990 --> 06:38.290
We now have taken care of serialization for our four new variables, and we can add getters and setters.

06:38.290 --> 06:44.710
But before we do that, I'm going to tackle the bonus challenge, serialize the gameplay tag for damage

06:44.710 --> 06:45.040
type.

06:45.040 --> 06:49.930
Now, this one is a little bit more complicated, but nothing we can't handle.

06:49.930 --> 06:56.680
We can just take a look at how we did it for the f hit result and as you can see, the F hit result

06:56.680 --> 07:06.490
here on our custom effect context is a protected member variable, which is a shared pointer.

07:06.520 --> 07:07.870
It's a smart pointer.

07:07.870 --> 07:13.560
So this is one of those few cases where you'll see a hit result stored as a pointer.

07:13.690 --> 07:17.170
The member on the effect context is a shared pointer.

07:17.170 --> 07:20.680
So that's what we're going to have in our ability types.

07:20.680 --> 07:30.440
So we're going to have a shared pointer of type F gameplay tag instead of hit result, we're going to

07:30.440 --> 07:31.790
call it damage type.

07:31.790 --> 07:33.620
Now we don't give this a new property.

07:33.620 --> 07:35.150
It's a shared pointer.

07:35.180 --> 07:39.350
Garbage collection is not handled for shared pointers by you property.

07:39.350 --> 07:45.260
The shared pointer and other associated smart pointers handles the automatic memory management.

07:45.560 --> 07:56.060
So now that we have a gameplay tag, let's take a look first at way up here where we have our hit result.

07:56.090 --> 07:59.930
We're just checking to see if it's a valid hit result before flipping the bit.

08:00.010 --> 08:01.760
We're going to do that here.

08:04.190 --> 08:10.550
So we're going to say if and we're going to use damage type dot is valid.

08:11.240 --> 08:15.320
If it's a valid pointer, then we'll flip bit 13.

08:15.980 --> 08:19.970
And then down here we can see what's going on for the hit result.

08:20.000 --> 08:23.210
If that bit has been flipped, we do something.

08:23.210 --> 08:28.250
If we're loading, if we're in the loading mode, then think about this.

08:28.250 --> 08:33.940
We're not saving, we're loading, which means the hit result has already been serialized.

08:33.950 --> 08:39.830
Otherwise we wouldn't be inside this if statement and we're about to unserialize it.

08:40.580 --> 08:44.810
So what we do is check if that hit result pointer is valid.

08:44.840 --> 08:47.960
If it's not, then we create a new one.

08:47.960 --> 08:54.710
We dynamically allocate a completely new shared pointer for the hit results because there doesn't exist

08:54.710 --> 08:55.410
one yet.

08:55.430 --> 09:02.750
After that we can take that hit result and call net serialize on it and that takes care of the archive

09:02.750 --> 09:03.740
business.

09:03.780 --> 09:04.340
Right.

09:04.340 --> 09:07.190
It's like doing this for all types.

09:07.190 --> 09:08.810
That archive is overloaded.

09:08.810 --> 09:15.980
The left shift operator for archive doesn't have the left shift operator overloaded for hit results,

09:15.980 --> 09:17.860
but hit results can handle it.

09:17.870 --> 09:22.700
It takes the archive, the map and the boolean in as input parameters.

09:22.730 --> 09:29.750
We're going to follow this same pattern for our gameplay tag so we can copy this whole if statement.

09:30.520 --> 09:32.620
And all the way down at the end.

09:32.650 --> 09:36.850
We're going to check to see if that 13th bit has been flipped.

09:36.970 --> 09:43.090
And we're going to also see if the archive is loading and then we'll check our damage type.

09:43.090 --> 09:45.570
We're going to say if damage type is valid.

09:45.580 --> 09:53.800
If it's not, notice the negation operator, then we create a new damage type in a shared pointer of

09:53.800 --> 09:55.960
type F gameplay tag.

09:57.410 --> 10:03.380
And we create dynamically a new gameplay tag in this shared pointer.

10:03.800 --> 10:10.250
And by the way, Ryder says you can make this with make shared if you wanted to do that.

10:10.780 --> 10:16.810
Now, after we've created that new shared pointer and assigned it to damage type, if we're in the loading

10:16.810 --> 10:20.080
mode, then we take damage type and net serialize.

10:20.080 --> 10:22.150
We do that whether we're saving or loading.

10:22.150 --> 10:24.940
But if we're loading, we had to create a new one.

10:25.540 --> 10:32.260
Okay, so now that we're serializing these based on rep bits, it's very important that we come back

10:32.290 --> 10:42.190
up to our serialized bits because we're now serializing more than just nine before we were serializing

10:42.190 --> 10:43.540
nine of those bits.

10:43.570 --> 10:44.680
Now we have.

10:46.060 --> 10:47.260
For more.

10:47.260 --> 10:52.840
So now that it's a total of 13, we have to pass that in to serialized bits.

10:53.080 --> 10:55.930
So this will now be a 13.

10:56.440 --> 10:57.340
All right.

10:58.180 --> 11:03.460
So now we've handled net serialize for our damage type gameplay tag.

11:03.460 --> 11:10.180
And the last thing to do, at least in this struct, is to create some setters and getter functions

11:10.180 --> 11:12.100
in our ability types.

11:13.610 --> 11:18.890
So we'll go up here and we'll have setters and getters for each of our new variables.

11:19.480 --> 11:27.640
So first the getters we're going to make a bool called is successful debuff.

11:28.900 --> 11:34.960
It'll be const and return that boolean b is successful debuff simple enough.

11:35.080 --> 11:40.870
We'll also have a float returning function called get debuff damage.

11:41.800 --> 11:45.220
Const and it will return debuff damage.

11:50.920 --> 11:58.690
Let's make a float called get debuff duration, which is const and returns debuff duration.

12:01.340 --> 12:05.030
We'll have a float called get debuff frequency.

12:08.140 --> 12:18.520
Const return debuff frequency and we'll have a function that returns a shared pointer of type F gameplay

12:18.520 --> 12:22.870
tag called get damage type.

12:24.400 --> 12:27.400
This will be const and we'll return damage type.

12:28.270 --> 12:30.340
So there's our new getters.

12:30.370 --> 12:31.990
We need setters as well.

12:33.060 --> 12:39.000
So we're going to have void set is successful debuff.

12:44.180 --> 12:48.320
Which will take in a bull called B and is debuff.

12:48.560 --> 12:49.910
We'll just call it that.

12:52.250 --> 12:56.840
And we'll set b is successful debuff equal to b and is debuff.

12:59.850 --> 13:03.750
We'll have a void function called set debuff damage.

13:06.260 --> 13:10.670
Which takes a float called in damage.

13:12.730 --> 13:16.660
And sets debuff damage to end damage.

13:18.520 --> 13:21.310
We'll have a void function set debuff.

13:22.330 --> 13:29.440
Duration, which takes a float called in duration and sets debuff duration.

13:34.080 --> 13:35.790
Equal to in duration.

13:37.080 --> 13:40.050
We'll have a void set debuff frequency.

13:42.100 --> 13:51.190
Taking in a float in frequency and setting debuff frequency to in frequency.

13:56.650 --> 13:59.110
So with that, we have setters and getters.

13:59.110 --> 14:06.310
And perhaps the last step of all of this is to add some functions to our aura ability system library

14:06.340 --> 14:14.350
that can set these by taking in input parameters, including a gameplay effect context.

14:14.590 --> 14:22.240
So we'll go ahead and open up our ability system library and all the way up at the top is where I'm

14:22.240 --> 14:26.050
interested because we have a couple of functions.

14:26.050 --> 14:28.150
Actually, it's not exactly at the top.

14:28.150 --> 14:32.200
We have is blocked, hit is critical, hit and so on.

14:32.230 --> 14:39.820
I'm going to make getters that take in effect context handles that correspond to my getters here is

14:39.820 --> 14:43.120
successful, debuff get debuff damage and so on.

14:43.240 --> 14:49.690
So I'm going to take is blocked hit, I'm going to copy it and paste it and I'll have a static bool

14:49.690 --> 14:54.670
that is called is successful debuff.

14:55.940 --> 14:58.490
And it can have all the same stuff.

14:59.620 --> 15:00.820
Same category.

15:00.820 --> 15:01.840
Blueprint pure.

15:01.870 --> 15:02.980
All of that.

15:03.100 --> 15:07.270
I'll also declare a new function that returns a float.

15:09.040 --> 15:19.300
And this will be called git debuff damage and I'll make three more functions that return a float that

15:19.300 --> 15:21.130
get the other debuff parameters.

15:21.160 --> 15:23.080
Get debuff duration.

15:25.310 --> 15:27.380
Get debuff frequency.

15:32.700 --> 15:34.170
And I think.

15:34.260 --> 15:35.700
Is that it?

15:36.570 --> 15:36.930
Okay.

15:36.930 --> 15:39.810
That's all of the debuff functions.

15:39.810 --> 15:42.300
The last one would be get damage type.

15:43.750 --> 15:51.070
I'd like jet damage type to just return a gameplay tag for me, so I'm going to go ahead and make another

15:51.070 --> 15:55.690
function, but this will just return a gameplay tag.

15:57.100 --> 16:01.570
We'll handle all the pointer business in the function to make it easy.

16:01.570 --> 16:04.600
So this will be get damage type.

16:06.180 --> 16:08.700
Okay, so we have a number of new functions.

16:08.730 --> 16:10.320
Five to be exact.

16:10.350 --> 16:14.460
Let's highlight them all and generate definitions for all of them.

16:15.600 --> 16:21.210
Now these are going to be similar to their counterparts like is blocked hit, for example.

16:21.240 --> 16:30.150
We're going to get our aura effect context use a static cast to for a gameplay effect context and then

16:30.150 --> 16:36.630
return the value that we retrieve from the getter function on the aura effect context.

16:36.630 --> 16:46.050
So really I can just copy that, paste it over here and call is successful debuff we'll do something

16:46.050 --> 16:48.420
similar for get debuff damage.

16:48.420 --> 16:57.450
The difference here is we're going to have to call get debuff damage and if this, if fails we have

16:57.450 --> 16:58.230
to return a float.

16:58.230 --> 17:00.120
So it's got to be zero.

17:00.770 --> 17:08.660
So I'll copy this, we'll paste it in get debuff duration only we're calling get debuff duration and

17:08.660 --> 17:14.210
we'll paste it in get debuff frequency only we're calling get debuff frequency.

17:18.020 --> 17:21.830
Now the gameplay tag situation is a little bit different.

17:21.830 --> 17:24.260
So how are we going to handle that?

17:24.440 --> 17:32.750
Well, let's start by copy pasting and what we return down here would be an F gameplay tag.

17:32.750 --> 17:33.410
Right.

17:33.650 --> 17:34.730
An empty one.

17:34.910 --> 17:38.360
But here is where we're going to do something a little different.

17:38.390 --> 17:44.780
What we have to do is check if we take the or effect context, we get damage type.

17:45.780 --> 17:50.010
What we call is valid on it got to be valid.

17:50.010 --> 17:53.970
And if it is valid then it's safe to dereference that pointer.

17:53.970 --> 17:59.550
So we say return and we dereference or effect context get damage type.

18:01.030 --> 18:07.990
That way we safely dereference and if we get to the end we return an empty gameplay tag.

18:08.500 --> 18:12.760
Okay, let's go ahead and compile and make sure that we haven't made any mistakes.

18:14.630 --> 18:21.740
And with that we have a successful compile and we now have some easy to use ability system library functions

18:21.740 --> 18:26.980
that we can pass in an effect context handle to set these parameters.

18:26.990 --> 18:33.980
We know that our effect context and our ability types has some additional parameters in particular ones

18:33.980 --> 18:38.030
related to debuff and it also knows its own damage type.

18:38.060 --> 18:45.140
This is going to be really useful because we can pass that info along in the effect context and use

18:45.140 --> 18:47.000
it later in the damage pipeline.

18:47.510 --> 18:48.470
Excellent job.

18:48.470 --> 18:51.170
We'll continue with this in the next video.
