Wednesday 15 May 2024

Broken Fairy Wings Project - Player Stats 01 + Damage Types 01 - 15/05/24

 Over the last week, I worked on adding in the different stats that I would be using for both the player and the enemies when in combat. I also worked on adding in damage types that would allow the player to deal more or less damage depending on the element of the attack.

Firstly, I worked on the players stats. I decided to go with 5 other stats to be added along with the stats already in the player (Speed, Mana  and health). These stats are Defence, which determines how much physical damage is reduced by, Strength, which determines how much damage a physical attack causes, Intelligence, which determines how powerful magic attacks and healing are, Wisdom, which determines how much magic damage is reduced by, and Luck, which determines the chance of getting item drops and critical hits.

To start, I went about adding these stats into the save data, the overworld character and the combat character. This way, I will be able to save and transfer the stats over to other characters, along with setting any changes made either by stat boosters or from levelling up.


From there, I started to add the stats into some of the action events, along with the player damaged event. The first of these events I worked on was the AnyDamage event, where I added the defence stat and used it to subtract the damage taken before dealing damage to the players health. I also added in a check to see if the enemies damage was less than 0 as I didn't want any errors occurring if that happened. For now, It just prints a print string indicating the damage taken was 0.

Afterwards, I went through all of the attacking and healing actions the player could make, and added in the respective player stat to them, with attacking actions having the stats added to the damage value, and healing actions having the stats added to the add health calculation. I also add space in between the stats and the end node for these calculations to add in more variables and values from buffs and de-buffs when I blueprint them in.

From there, I was planning on adding a second calculation to the player takes damage event where it would determine which type of attack it was. However, I didn't know how I should go about it, so I decided to look up a video on determining damage types and found a pair of videos from Ryan Laley that goes over an entire damage type matchup system, as well as how to cast to that system to determine how much damage a target takes. Using this, I made an initial damage type table and have plans to rework it later.

Links: Unreal Engine 5 Tutorial - Elemental Damage Table Part 1: The Damage Table (youtube.com)

Unreal Engine 5 Tutorial - Elemental Damage Table Part 2: Applying Damage - YouTube

To start, I created an enumerator and added in three damage types to it, these being the initial types that I will be using to test the blueprint out.


I then made a new structure and added the enumerator as a variable inside and made it into a mapping variable for later use.

Afterwards, I created a data table using the new structure so that I could  determine how each of the damage types would react with one another.

Going back into the new structure, I then went into default values section so that I could add in a base value to each of the damage types, in this case, all of them being 1. This way, the values recorded would be added to the data table without me having to constantly copy the elements from one data set to the other.

From there, I went back into the data table and added some data sets to act as the damage reactions to an element being hit with a different damage type. For this, I would first add in the damage type that is being targeted, then adjusting the values below to determine the multiplier a damage type would deal when hitting a enemy of that element, for example, my current blunt types have a multiplier of 1 when taking damage from any damage types whilst my fire type takes 2 time damage from slashing attacks and half from fire type attacks.

After sorting out the data table, I then went and made some new damage types, one being the base damage type which I would use as the parent for other damage types, and the others being the respective damage types. I then added a variable of the enumerator in for a calculation in a function, with each damage type having the variable match the damage type.

Continuing on, I then created a function library and made a function to calculate the overall damage multiplier based on the element types of the enemy and the damage type of the attack.  

To start, I added two pins, one being an enumerator for the incoming damage type and another being a enumerator array for the element types of the enemy, with it being an array for if they have multiple types. I then turned the incoming damage into a string and then a name so that I had an accurate name to be used in a Get Data Table Row node. 

This node would allow me to get the data table I made for the damage types and I could insert the converted name into the row pin of the node, allowing it to check if it matches a row in the data table too which I break the structure of the row and get the mapped response of the damage type. If the row is not found then it will simply return as a multiplier of 1. 

However, if the row is found, then it will get the enemies elemental types and use the mapped damage response to find the damage multiplier value for each element, this value being based on the data tables response and not the default. I then made a local variable array to store these multipliers and had the values checked before to be true or not. Once all of the values are added, I then used a for each loop of the values and multiplied them with a new local variable, which I set the value to 1, before setting them as the new value of the variable. Finally for the function, I used the results of the variable as the damage multiplier and plugged it into a return node.

After creating the function, I went into my test enemy and made a variable for the element types to be used with the newly created function. I then went to the AnyDamage event I had setup already and casted to the base damage type, that I setup earlier, from the damage type node of the event. Once casted, I then got the damage type of the attack and connected it to the newly created function. I also added a Boolean variable to the base damage type, though this is for a later blueprint.

Once I added the function in, I then went an made the function a Pure function by ticking the Pure box when selecting the function in the library. This allows the function to take up less space and not need as much processing power dedicated to it. 

Finally, I connected the damage value into the sequence, with it being multiplied by the damage multiplier to determine the final damage value before dealing the damage.

Over the next week, I will be working on adding the stats the enemies, incorporating more of the stats into different actions/blueprints, and adjusting the damage type table to have more damage types, along with it potentially using monster types, rather than damage types to determine weaknesses.

Wednesday 8 May 2024

Broken Fairy Wings Project - Enemies 01, Encounters, Targets and Attacks - 08/05/24

For this week, I went to work making two blueprints for the enemies. These being, setting the encounter the player will receive when walking into one, choosing which enemy to target, and a basic attack that damages the player. I also readjusted some of my blueprints to work when multiple enemies are in the encounter.

To start, I worked on adding in the multiple potential fight encounters. To start, I first got some make literal name nodes and attached them into an array which I then attach to a get random item node from the array pin. I then made a new name variable in the enemy blueprint that will get the chosen random name and set it in the new variable.

I then made a new custom event in my game instance that collects the encounter when the player walks into the enemy. 

I then went into the overworld controller and got the reference to the save data actor and the instance reference so that I could put the saved encounter name into a new variable in the save data.
(I changed where the save reference is gotten)

Finally for the encounter blueprint, I placed some more spawners in the combat map and had the instance grab all of them so that it could check which spawners should be activated with a for each loop. Inside the for each loop, I first checked what the index of the spawner is, with it automatically spawning an enemy if its index is 0. If it is greater, then it will check which encounter name was saved as well as if it met the index requirements, which is based on the encounter name. Once sorted, it will then activate the spawn enemy in the spawner of the appropriate index in each loop.
(here is the Blueprint working in the combat map)

From there, I then decided to make the choose target blueprint in the combat character so that the player could choose which target is the priority target. For this, I used some keyboard letter events and made a new variable which tracks the index of the collected enemies and increased/decreases it depending on which button is pressed. If the E button is pressed, then it will increase the index by 1 and check to see if the number is greater than the last index of the gathered enemies. If so then it will get the first enemy from index 0 and set it as the players target before setting the enemy index back to 0

If it is Q, then it will decrease the index by one before checking if the value is less than 0, with it getting the last index if it is less than, so that it can use the index to find the last enemy in the gotten enemies array. From there, it sets the index to the last index as well. If in both events the indexes don't meat the criteria, then it will just get the enemy that matches the index and set it as the new target.

Afterwards, I then added a do once to the player turn blueprint so that when players turn comes up again, it doesn't re-target the first enemy. Instead, I had it assign the new target only when the targeted enemies is defeated, with it firing off when the all enemies array is not empty.

One quick change I made before the enemy attack blueprint was to fix an issue with abilities that was the same as the one when using Items in combat. For this, I just removed the remove from parent part in the click button event of the ability button and added it on to the end of the set actors turn node in the combat character, meaning unless an ability works, it will keep the combat menu open.

To start the enemy attack, I wanted to first make a simple attack that just targets the player. For this, I expanded the enemy acts custom event by adding in a random float in range node to randomly pick a number and checks to see if it is less than 6. If it is, then it will damage the player, dealing 2 damage. If not, then it will deal 4 damage, acting like a second type of attack. It then continues as normal.

From there, I added in a damage blueprint to the player, with it kicking the player out if the players health reaches 0.

Afterwards, I went back into the combat controller to adjust the turn tracker. To start I removed the players initiative from the collected initiative array so that I can use the array solely for comparing indexes with the enemies list array. I also moved the find all enemies section in the begin play event in here so that I can grab all of the enemies again and their initiatives when they have their turn.

Afterwards, I made some new checks to the set actor turn custom event so that the enemies do not ignore the player not acting yet. For this, I first checked to see if the player has acted or not. If the player has, then it would check if the collected initiative array was empty before to see if it is  

From there, I used the index of the collected initiatives to check which enemy should move first out of the list. To do this I checked if the indexes of both the max value collected initiative and the index of the enemies list in the for each loop were equal, with it continuing the blueprint if it does.

Continuing on, I then added a section for removing the enemy from the enemies list array so that if the enemy is defeated or it's speed decreases for any reason, then it won't be miss aligned in the checks when the initiatives are collected again.

Lastly for this blueprint, I made an adjustment to the remove from list custom event, which activated when an enemy is defeated. For this change, I first got the collected initiatives array and checked which initiative index matched the destroyed enemies index, with it removing the matching initiative. Once the for each loop is complete, it will then remove the enemy from the list, making sure there are no errors when repeating the collect initiatives custom event.

I then added in a check at the start of this section to see if the defeated enemy was in the list because if it were not, such as it having already acted before being defeated, it would likely cause an error when the for each loop was completed. So I just used a contains node and checked it with the defeated to see if it was in or not, with it continuing the blueprint if its and stopping it if not


For this week, I will be working on adding in the different stats for the player and enemies, as well as a level up system that increases these stats.

Wednesday 1 May 2024

Broken Fairy Wings Project - Combat Menu 03, Fleeing and Item - 01/05/24

 Over last week, I worked on blueprinting the flee from combat button and using items in both the overworld and combat maps. The first blueprint I worked on was the fleeing blueprint. I was torn on deciding if the enemy in the overworld should be destroyed or to just have its collision turned off for a moment then before turning it back on. In the end I decided to just have it destroy the actor when the player flees.

To start, I created a Click button event for the flee button and checked if it is the players turn by seeing if the Hasn't Acted Boolean is true or not. If it is true, then it will fire a custom event in the combat player actor before removing the combat menu from the viewport.


Inside the combat player, I added a new integer to act as the speed stat of the player and I added a speed stat in the enemy actor as well so that I can use them determine the initiative of the player and enemy and to be used in determining if the player flees. 

From there I made the fleeing custom event where I first gathered all of the enemy's speed stats and added them into an integer array, I then get the highest value of that array and use it then add 5 to it so that it acts as the goal for fleeing the enemy. To see if the player can flee, I used the same nodes as the initiative to randomly generate a number, and if that number is greater than or equal to the enemies goal, it will fire off the end combat custom event. If it doesn't match/beat it, then it will fire the pass action and clear the integer array so that it doesn't keep any values from defeated enemies.

I then added the speed stat to the saving and loading functions so that if the players speed increases, I.E, from levelling up, it will be permanent. I will be adding extra variables for temporary and item buffs later.


Another edit I made before going into the using item blueprint was to change the enemy defeated custom event so that it requires all enemies to be defeated rather than just one. For this, I first got the enemies actor array that is used to gather all of the enemies in the combat level and got a remove node from it. I then connected this node to the custom event so that when an enemy fires the event, it will be removed from the array. If the array is empty, then it will save the relevant data before casting to the game instance and firing the end combat custom event. I also connected the E button event for debugging purposes.

After creating the fleeing blueprint, I then worked on adding an item list to both the pause menu and combat menu so that the player could use an item when the list is shown. To start, I made the item button in the combat menu visible, along with adding a button and naming it items in the pause menu. From there, I duplicated the wing list, object and structure and renamed them with item instead. I also deleted all of the unnecessary code and renamed and created new versions of all relevant variables and events to have item in their name as well.

From there I made a modification to the construct blueprint to determine if the level is a combat level or not. If it is, then it will cast to the combat player and set it as reference (I forgot to connect the as node to the reference in the screenshot, I have since fixed this). If it were not the combat level, then it would cast to the third person player and set it as a reference for a different variable.

From there, I duplicated the custom event for creating the wing list and adjusted it for the item list, and I did this for both the combat and pause menus. This way, I can create the list blueprint very quickly. 

Once I finished working on the item list creation blueprint, I then added the new variables, along with another item variable I made to flesh out the items list, to the save and load functions in both the combat and third person player so that when an item is used in one level, the amount remaining is transferred over to the other.

Inside the third person player, I added the node to fire the custom event to create the item list at the end of the pause menu creation blueprint so that it is generated at the same time as the wing list.

I then duplicated the collecting wing pieces function in the third person player, using the newly created variables, this way, it will update whenever the player collects an item out in overworld or from a chest/container.

Afterwards, I then made a use item function, which I made in the third person player and added to the combat player so that player can use the items in both players. For this function, I first checked which item was using by checking if it equalled a specific item. If it did, then it would use the item. 


For healing items, like the spring water and honey, it would also check if there respective stat, like HP and Mana, is at max as well so that if it is at max, then it will not be used. if it isn't at max then it would restore a portion of the respective stat, making sure they don't go over the max of those stats. They would also reduce their items respective amount by 1 in the items amount array.

Once the function was made, I then added custom events to the two player blueprints and connected the function to them, with it also passing the turn when the player uses an item in combat.

Afterwards, I went back into the item list widget and made a click button event for when the player wants to use one of the items. When clicked, it will check if the amount of the respective item is greater than 0, with nothing happening if it is 0. If it is greater, then it will check the map to determine which reference it should use. If it is the Combat player, then it will first check if the hasn't acted Boolean is true or not, firing off the use item custom event if true. it would then reset the text and remove the combat menu from the viewport.

If it was third person player, then it would just fire the use item blueprint and reset the text.

To make sure the blueprints were working, I added a item actor that had a name variable that I could set in the editor. I then made a simple overlap blueprint, with it firing off the add item custom event/function in the third person player.

(Here is how the item list looks like in the pause menu)
(Here is how the pause menu looks in the combat menu)

After play testing the blueprint however, I noticed some mistakes I made. The first was that in the combat player, it would remove the menu, even if an item had no effect. to fix this, I made a Boolean variable and had it set to true if an item wasn't used/had no effect, and set to false if an item was used. This way, I could use the Boolean to determine if the 

This way, I could use the Boolean to determine if it should do nothing, or fire the pass action and then remove the combat menu from the viewport.

I also noticed a problem for both references in the item list. That being they would still change the amount, even if an item had no effect. So, I removed the reset amount portion of the blueprint and created a custom event for this purpose, which was mainly for the third person reference as the combat player would collect the new amounts when it becomes their turn again.

Lastly, I added a bit on the end of the use items function in the third person character so that it would update the respective item amount when used. For this I would connect off the end of each item and get all of the item list widgets before using a for each loop to see which item list matches the item used. It then fires the reset amount custom event in the specific item list.


Over the end of this week and the start of next week, I will be working on the enemies blueprint and AI in both the overworld and in combat.