WEBVTT

00:07.040 --> 00:08.270
Welcome back.

00:08.480 --> 00:10.970
Now we have our exec calc damage.

00:10.970 --> 00:15.890
And here we're actually calculating how much damage we should do.

00:15.980 --> 00:18.820
Now, this is just generic damage.

00:18.830 --> 00:25.820
We don't really have any concept of damage types, but if we did, we could respond to each damage type

00:25.820 --> 00:31.850
differently by having some kind of resistance to that damage type, for example.

00:32.090 --> 00:36.590
So damage types are implemented in lots of RPG games.

00:36.590 --> 00:41.960
So we're going to explore a way to implement damage types in this project.

00:41.990 --> 00:46.220
Now I'd like to identify damage types by gameplay tag.

00:46.370 --> 00:52.400
Yes, Unreal Engine does have a built in damage type based on the Ew damage type class.

00:52.400 --> 00:53.870
And it's okay.

00:53.870 --> 00:59.960
It's good for adding static functions to a damage type and checking to see if you're using that damage

00:59.960 --> 01:02.870
type and accessing static functions on it.

01:02.870 --> 01:08.190
They're not supposed to be instantiated or anything, and that's an okay way to implement damage types.

01:08.190 --> 01:14.790
But I like the idea of using gameplay tags to identify damage types as they're more lightweight, don't

01:14.790 --> 01:20.370
require you to cast, and they're very easily passed around throughout the gas system.

01:20.370 --> 01:24.120
So I'd like to use gameplay tags for damage types.

01:24.120 --> 01:29.670
Now I'd like to add a gameplay tag for our first damage type that we'll implement.

01:29.670 --> 01:35.670
And what makes the most sense right now would be fire because we have a firebolt ability.

01:35.670 --> 01:42.480
So our first step for implementing damage types is to define the gameplay tag for the fire damage type

01:42.480 --> 01:45.210
and that's going to be an aura Gameplay tags.

01:45.210 --> 01:51.660
So we can open aura gameplay tags and we do have a gameplay tag called Damage.

01:51.660 --> 02:00.840
I'd like to have a gameplay tag for the fire type, so I'm going to make an gameplay tag called Damage

02:01.500 --> 02:03.210
Underscore Fire.

02:03.210 --> 02:10.830
So this will be the first damage type that we have now I can go into the CPP file and define this gameplay

02:10.830 --> 02:17.250
tag, so I'll put it just under damage and copying and pasting damage.

02:17.250 --> 02:20.370
I'm going to change this to damage underscore fire.

02:20.400 --> 02:28.530
We're going to add a native gameplay tag called Damage Dot Fire and the F string comment will say fire

02:28.800 --> 02:30.000
damage type.

02:30.000 --> 02:33.390
So now damage dot fire is a gameplay tag.

02:33.540 --> 02:36.360
Now how are we going to implement damage types?

02:36.450 --> 02:41.670
Well, we could have the concept of a damage type for our gameplay ability.

02:41.700 --> 02:49.770
We know that our gameplay ability or a gameplay ability, which is our base ability class has a scalable

02:49.770 --> 02:51.060
float for damage.

02:51.060 --> 02:56.610
So if we go to aura gameplay ability, here it is f scalable float.

02:56.790 --> 03:04.800
Now we could have a simple gameplay tag called damage type on our ability if we wanted to just be able

03:04.800 --> 03:08.880
to apply damage of a single type for a gameplay ability.

03:08.910 --> 03:14.730
We could also have our ability be capable of applying multiple damage types.

03:14.730 --> 03:21.300
In that case, it might be nice to have a map from gameplay tag to scalable float for the different

03:21.300 --> 03:22.380
damage types.

03:22.410 --> 03:27.930
Either way, we're going to want to have the damage type information in our ability now at this point

03:27.930 --> 03:33.870
because we're adding more things to our gameplay ability class that may not be used by all gameplay

03:33.870 --> 03:34.710
abilities.

03:34.710 --> 03:42.840
I'd like to subclass or a gameplay ability into a specialized class that's capable of causing damage,

03:42.870 --> 03:46.860
something like aura damage ability, for example.

03:46.860 --> 03:54.360
So for that reason I'd like to start the editor and create a new gameplay ability class based on our

03:54.360 --> 04:01.650
Aura gameplay ability base class, and I'd like that to be a special aura gameplay ability that's capable

04:01.650 --> 04:03.210
of causing damage.

04:03.960 --> 04:12.000
So I'm going to go ahead and just go straight to my C plus plus classes or public ability system abilities

04:12.000 --> 04:16.470
folder and make a new class based on aura gameplay ability.

04:16.470 --> 04:21.750
So I'm going to right click, make a new C plus plus class based on this ability and I'm going to call

04:21.750 --> 04:26.130
this aura damage gameplay ability.

04:26.130 --> 04:28.800
So let's go ahead and create that class.

04:28.980 --> 04:34.980
I'm going to close the editor down and now we should have an aura damage gameplay ability and we'll

04:34.980 --> 04:38.270
put any damage capabilities in that class.

04:38.280 --> 04:42.600
Now Aura projectile spell is just based on aura gameplay ability.

04:42.600 --> 04:46.560
So if we want to reparent it, we have to do that ourselves.

04:46.560 --> 04:53.880
So I'm going to go to the public folder ability system abilities and open aura projectile spell and

04:53.880 --> 05:00.360
expand the include so I can see them and I'm going to change its parent from aura gameplay ability to

05:00.360 --> 05:03.750
aura damage gameplay ability.

05:03.750 --> 05:10.080
For that reason I have to include aura damage gameplay ability instead.

05:10.080 --> 05:17.160
And now our gameplay ability or a projectile spell is based on aura damage gameplay ability.

05:17.190 --> 05:24.390
Now for that reason we have this damage gameplay effect class on aura projectile spell that should be

05:24.390 --> 05:28.860
moved over to aura damage gameplay ability and that should be protected.

05:28.860 --> 05:35.580
So I'm going to use control X to cut that and go over to aura damage gameplay ability, add a protected

05:35.580 --> 05:40.200
section and paste in the damage gameplay effect class.

05:40.320 --> 05:47.190
So only aura gameplay abilities derived from aura damage gameplay ability should need this.

05:47.220 --> 05:47.700
Now.

05:47.700 --> 05:54.300
I'm also going to go to aura gameplay ability and I have this scalable float called damage that's not

05:54.300 --> 05:56.490
needed in the base class.

05:56.490 --> 06:03.630
So I'm going to control X to cut that and head on over to aura damage gameplay ability and paste it

06:03.630 --> 06:04.220
in.

06:04.230 --> 06:11.500
Now the thing is we should have a damage type and if we want to be able to have multiple damage types

06:11.500 --> 06:17.530
and values for the damage, for a damage gameplay ability, we should do something like have a team

06:17.530 --> 06:21.580
map as this can map an gameplay tag.

06:23.530 --> 06:29.290
Two f scalable float and we can call this damage types.

06:30.600 --> 06:39.690
Now we can make this new property with edit defaults only and we can place it in category combat.

06:40.740 --> 06:43.290
Actually, I'd like it to be in category damage.

06:43.410 --> 06:49.710
And with that we don't really need the damage scalable float, but we're using it elsewhere in our code.

06:49.710 --> 06:52.740
So we're going to need to fix that if we remove damage.

06:53.400 --> 06:56.040
Now, where are we using this scalable float?

06:56.070 --> 06:58.890
We're using it in aura projectile spell.

06:58.920 --> 07:07.830
So if we go to aura projectile spell dot CP and find where we're using the damage scalable float, we'll

07:07.830 --> 07:12.800
see that we're calling get value at level here and we're just kind of passing in ten.

07:12.810 --> 07:17.400
We're kind of cheating here so we get damage at level ten for this ability.

07:17.670 --> 07:22.800
But if we get rid of damage, that means we're going to have a team map and we should really get the

07:22.800 --> 07:27.360
value in the team map for each gameplay ability.

07:27.360 --> 07:32.510
And then we should assign tag set by color magnitudes for each damage type.

07:32.520 --> 07:40.230
So that means we're going to need to loop over that team map and do this for each damage type.

07:40.230 --> 07:43.260
So what I can do here is place A for loop.

07:44.930 --> 07:51.680
I'm going to say auto reference pair in damage types.

07:52.970 --> 07:58.940
And here in damage types, we're going to take this const float scale damage.

07:59.360 --> 08:09.860
I'm just going to copy it into here and it's going to be pair dot value, dot get value at level and

08:09.860 --> 08:14.590
I'm going to go ahead and pass in get ability level here.

08:14.600 --> 08:22.700
So we got the scaled damage for each damage type and damage types and then we can assign the tag set

08:22.700 --> 08:24.110
by color magnitude.

08:24.110 --> 08:26.450
So I'm going to copy that line into here.

08:26.480 --> 08:28.460
We pass in the spec handle.

08:28.980 --> 08:36.180
And instead of gameplay tags damage, we're looping through this pair where the key is the gameplay

08:36.180 --> 08:37.230
tag for damage.

08:37.230 --> 08:47.370
So we're going to use pair dot key for the damage type and scale damage will be retrieved from that

08:47.370 --> 08:52.830
pair as well as we're getting it from pair dot value get value at level.

08:53.190 --> 09:00.060
So now with this for loop, we can have multiple damage types and we don't need this scaled damage here

09:00.540 --> 09:06.270
and we don't need this assign tag set by color magnitude so we can remove those.

09:06.780 --> 09:11.850
Now that's not the only place where we're checking for the damage tag, is it?

09:11.970 --> 09:17.370
We need to take a look at exec calc damage and we can search for set by color.

09:17.640 --> 09:24.450
And we can see here that we're getting the set by color magnitude straight up using the damage gameplay

09:24.450 --> 09:25.020
tag.

09:25.020 --> 09:28.080
But now we need to do this for all damage types.

09:28.080 --> 09:33.040
So it'd be nice if we just knew what all the damage types are.

09:33.040 --> 09:38.680
Well, we could keep them all together in some kind of array or collection somewhere.

09:38.680 --> 09:44.770
For example, we can go to aura gameplay tags and we can have a t array of gameplay tags for the damage

09:44.770 --> 09:45.520
types.

09:45.760 --> 09:49.360
So t array f gameplay tag.

09:50.640 --> 09:56.190
And we can call this damage types and we can add the damage types to this array.

09:56.220 --> 09:58.380
We can do that in the CPP file.

09:58.590 --> 10:07.320
So right here under damage fire after this gameplay tag has been created, we can take gameplay tags,

10:07.320 --> 10:09.180
dot damage types.

10:12.930 --> 10:13.710
And call.

10:13.710 --> 10:16.810
Add and add gameplay.

10:16.830 --> 10:19.410
Tags, dot damage fire.

10:19.410 --> 10:24.410
And then we can just make sure that each of the damage types is added to this array.

10:24.420 --> 10:29.610
And then we can always get the t array if we want to know how many damage types there are.

10:29.640 --> 10:32.610
So back to our exec calc.

10:32.640 --> 10:34.770
We can loop over that t array.

10:34.800 --> 10:47.490
We can say for f gameplay tag damage type tag in f or a gameplay tags get.

10:50.450 --> 10:52.330
Dot damage types.

10:52.340 --> 10:54.900
So we're looping through the damage types.

10:54.920 --> 10:57.830
Then we can get the set by color magnitude.

10:57.830 --> 11:04.790
So I'm going to make a const float here called damage type value equals.

11:04.790 --> 11:12.350
And we're going to call spec dot, get set by caller magnitude here, passing in the damage type tag.

11:14.210 --> 11:20.300
So since we're looping through all the different damage types, we can now add all of those damage type

11:20.300 --> 11:22.000
values to damage.

11:22.010 --> 11:26.510
So here I'm just going to set damage to zero as we create it.

11:26.510 --> 11:29.150
So float damage equals zero F.

11:29.670 --> 11:31.210
And then I'm going to add damage.

11:31.230 --> 11:36.120
Type value to damage for each damage type, but only if we find it.

11:36.120 --> 11:41.580
And remember, get set by caller magnitude has a optional float default.

11:41.580 --> 11:44.670
If not found, it's set to zero by default.

11:44.670 --> 11:50.330
So if it's not found, then damage type value will just be zero.

11:50.340 --> 11:58.920
So for that reason it's safe to say damage plus equals damage type value.

11:59.310 --> 12:06.330
So now if we have multiple damage types, we'll add the values set in our set by caller magnitude here.

12:06.420 --> 12:13.170
And we know that our projectile spell loops through all of the damage types and gets their value.

12:13.170 --> 12:19.740
So we're going to have to make sure that we set that damage type F scalable float pair for the fire

12:19.740 --> 12:20.670
damage type.

12:20.670 --> 12:23.820
So that takes care of exec calc damage.

12:23.820 --> 12:30.280
And later, if we decide to add resistance attributes for each damage type, we can check those and

12:30.280 --> 12:35.740
we can lower the damage for that given damage type based on that resistance.

12:35.920 --> 12:40.180
So the last thing to do is to take our aura gameplay ability.

12:40.180 --> 12:47.410
Actually, it's going to be our aura damage gameplay ability and remove damage altogether as we don't

12:47.410 --> 12:48.850
really need it anymore.

12:48.850 --> 12:55.600
And if we're still using it anywhere, a quick compile is going to give us a handy compiler error showing

12:55.630 --> 12:57.790
us, but I don't think we're using it anymore.

12:58.960 --> 13:03.760
So with a successful compile, we can go ahead and launch the editor.

13:05.450 --> 13:11.330
And with that, I'm going to go ahead and open up my firebolt gameplay ability.

13:11.330 --> 13:13.490
So that's an ability system.

13:13.490 --> 13:20.180
Gameplay abilities Fire Firebolt, gar Firebolt and under damage.

13:20.180 --> 13:23.360
We now have damage types instead of a scalable float.

13:23.390 --> 13:28.220
Now I can click plus to add one and now I have a key value pair.

13:28.250 --> 13:35.840
The key is the gameplay tag that's going to be damage fire and the value is going to be my CT damage

13:35.840 --> 13:40.310
curve table Selecting the curve Abilities Dot Firebolt.

13:40.430 --> 13:43.370
So now damage is handled a bit differently.

13:43.460 --> 13:49.100
And the cool thing about this is we could add multiple key value pairs to this map.

13:49.100 --> 13:57.530
Now at this point I only have the fire gameplay tag and I can't add a duplicate key to a map, so I

13:57.530 --> 13:59.240
really don't have any options here.

13:59.240 --> 14:02.780
I can only have one element here, so I'm going to have to delete that one.

14:02.780 --> 14:08.970
But once we add new damage types, we can have multiple and they'll all be applied if we want to do

14:08.970 --> 14:09.450
that.

14:09.450 --> 14:16.110
So now the only thing left is to see if our ability still causes damage.

14:16.620 --> 14:18.450
And it looks like we do.

14:19.510 --> 14:26.230
Now the numbers are lower because we're no longer cheating and passing in a ten for the ability level.

14:26.230 --> 14:29.680
We're just passing in the actual abilities level, which is one.

14:29.680 --> 14:33.430
So we're really only doing a little bit of damage.

14:34.540 --> 14:38.410
As we see that normally we're getting three damage.

14:38.410 --> 14:40.330
When it's a block, we get one damage.

14:40.330 --> 14:42.130
A critical hit is 51.

14:42.580 --> 14:45.490
So that's actually way too high.

14:48.030 --> 14:54.150
And if I go to look at my critical hit damage attribute, I see that it's 45.

14:54.180 --> 14:58.280
Now, that's way out of balance compared to my others.

14:58.290 --> 15:03.270
Critical hit chance is okay, but critical hit damage should not be 45.

15:03.420 --> 15:10.590
So before we wrap up, I'm going to just tweak that and we'll be tweaking these parameters for our attributes

15:10.590 --> 15:11.640
as we go.

15:11.850 --> 15:20.550
I'm going to go into ability system gameplay effects, default attributes, Aura, GE, secondary attributes,

15:20.550 --> 15:25.230
and I'm going to find my critical hit damage attribute.

15:25.530 --> 15:26.700
Here it is.

15:26.700 --> 15:29.550
And I'm going to take a look at my parameters.

15:29.550 --> 15:36.870
I'm going to expand modifier magnitude, attribute based magnitude, and it looks like I have my attribute

15:36.870 --> 15:38.310
based on.

15:39.790 --> 15:41.260
Armor penetration.

15:41.260 --> 15:43.870
So its base value is five.

15:43.870 --> 15:51.310
And for every armor penetration point we get 1.5 added, which must mean armor penetration is too high.

15:51.460 --> 15:54.130
So let's take a look at armor penetration.

15:54.430 --> 15:55.800
Here it is.

15:55.810 --> 16:03.100
We see that it's backed by resilience and it has a post-multiply additive value of 25.

16:03.310 --> 16:08.830
So if we lower this value, we'll lower our critical hit damage value.

16:09.070 --> 16:10.540
That's one option.

16:10.540 --> 16:17.800
So I'm going to go ahead and lower it to about 11 for the post-multiply additive.

16:17.980 --> 16:25.480
And this attribute is backed by resilience and we get 0.15 points added for every resilience point.

16:25.690 --> 16:34.060
And if we want critical hit damage to increase by a smaller amount for every armored penetration point,

16:34.090 --> 16:41.000
what we can do is we can go back down to our critical hit damage and lower our coefficient.

16:41.000 --> 16:50.480
So if we set this to about 0.05, for example, or 0.08, then we should see a smaller value for critical

16:50.510 --> 16:51.470
hit damage.

16:51.890 --> 16:59.390
Taking a look now, I see my critical hit damage is six, which is actually maybe a little bit on the

16:59.390 --> 17:00.380
lower side.

17:00.380 --> 17:03.170
So the coefficient could probably be.

17:03.840 --> 17:05.250
0.25.

17:05.280 --> 17:06.930
Let's see what we get now.

17:08.500 --> 17:11.350
Now we see a critical hit, damage of eight.

17:13.000 --> 17:19.030
And armor penetration is 12 I think critical hit damage of eight when armor penetration is 12 looks

17:19.030 --> 17:19.870
pretty good.

17:19.870 --> 17:25.930
And I'll go ahead and let my armor penetration be just a slight tad bit higher.

17:26.080 --> 17:32.800
I'll go ahead and get that post multiply additive value and increase it to about 16.

17:33.760 --> 17:36.070
And now we should see.

17:36.120 --> 17:38.300
Armor penetration is 17.

17:38.320 --> 17:40.240
Critical hit damage is nine.

17:40.270 --> 17:43.330
Let's go ahead and see how much we get.

17:44.370 --> 17:45.420
That's a block.

17:46.150 --> 17:47.830
Critical hit was 15.

17:48.070 --> 17:49.690
So a block is one.

17:51.890 --> 17:53.960
A blocked critical hit was 12.

17:56.500 --> 17:58.360
A normal hit was three.

18:00.120 --> 18:05.220
So I think a normal hit could be a little bit bigger.

18:05.220 --> 18:09.420
And that's all going to have to do with my scalable float, right?

18:09.510 --> 18:13.500
Because a firebolt has CT damage.

18:13.500 --> 18:21.320
If we open that and look at Firebolt, our scalable float starts off at a value of five at level one.

18:21.330 --> 18:26.610
So I think what I'd like to do is kind of bring this curve up just slightly.

18:27.970 --> 18:30.540
We'll have it start off at a value of ten.

18:30.550 --> 18:33.940
So we'll have it look a little bit more like this.

18:34.240 --> 18:35.590
I think that looks good.

18:36.130 --> 18:37.810
Saving that.

18:38.020 --> 18:40.450
Now, the whole damage just went up.

18:40.450 --> 18:42.670
So a regular hit that was five.

18:42.700 --> 18:45.640
A blocked hit is three regular hit.

18:45.640 --> 18:47.650
Five five blocked.

18:47.650 --> 18:49.450
Critical hit was 15.

18:49.900 --> 18:51.340
Let's see if we can get a critical.

18:55.500 --> 18:56.220
Critical hit.

18:56.250 --> 18:56.910
20.

19:00.580 --> 19:02.260
Okay, so that's looking better.

19:02.590 --> 19:04.330
I'm liking those values.

19:04.330 --> 19:06.100
I think that's looking good.

19:06.100 --> 19:09.760
And our enemies seem to start off with too much health.

19:09.760 --> 19:16.840
So at some point I think I'd like to tweak those settings so the level one enemies don't start off with

19:16.840 --> 19:21.490
so much health and their block chance is a little high.

19:21.520 --> 19:23.140
It looks like they're blocking too much.

19:23.140 --> 19:26.980
But again, that's because they're using the test ability.

19:26.980 --> 19:34.870
So in blueprints, ability system, gameplay effects, default attributes and then secondary attributes

19:34.870 --> 19:38.860
test we have that block chance just hardcoded here.

19:38.860 --> 19:42.220
So looks like it is 50%.

19:42.340 --> 19:48.190
Realistically, I'd like it to be closer to something like 15 so we won't see so many blocks.

19:49.070 --> 19:52.000
And most of the damage will be just regular.

19:52.010 --> 19:53.960
But that was a critical hit.

19:53.990 --> 19:56.450
Looks like our critical hit Chance is a little high.

19:56.540 --> 19:57.620
18.

19:58.410 --> 20:02.700
So that's we'll just keep in mind that that's a bit high and then we can.

20:03.540 --> 20:06.090
Tweak it later as we see fit.

20:06.630 --> 20:07.470
Okay.

20:14.010 --> 20:14.610
Excellent.

20:14.610 --> 20:16.800
So we now have damage types.

20:16.890 --> 20:22.320
The next step is to implement damage resistances to those damage types.

20:22.350 --> 20:24.780
Great job and I'll see you soon.
