├── .gitignore ├── Chapter02 └── MyCPP_01 │ ├── MyCPP_01.sln │ └── MyCPP_01 │ ├── Calculator.cpp │ ├── Calculator.h │ ├── MyCPP_01.vcxproj │ ├── MyCPP_01.vcxproj.filters │ ├── MyCPP_01.vcxproj.user │ └── main.cpp ├── Chapter03 ├── MyCPP_02 │ ├── MyCPP_02.sln │ └── MyCPP_02 │ │ ├── MyCPP_02.vcxproj │ │ ├── MyCPP_02.vcxproj.filters │ │ ├── MyCPP_02.vcxproj.user │ │ └── main.cpp ├── MyCPP_03 │ ├── MyCPP_03.sln │ └── MyCPP_03 │ │ ├── Calculator.cpp │ │ ├── Calculator.h │ │ ├── MyCPP_03.vcxproj │ │ ├── MyCPP_03.vcxproj.filters │ │ ├── MyCPP_03.vcxproj.user │ │ └── main.cpp ├── MyCPP_04 │ ├── MyCPP_04.sln │ └── MyCPP_04 │ │ ├── Calculator.cpp │ │ ├── Calculator.h │ │ ├── CalculatorEx.cpp │ │ ├── CalculatorEx.h │ │ ├── MyCPP_04.vcxproj │ │ ├── MyCPP_04.vcxproj.filters │ │ ├── MyCPP_04.vcxproj.user │ │ └── main.cpp └── MyCPP_05 │ ├── MyCPP_05.sln │ └── MyCPP_05 │ ├── Calculator.cpp │ ├── Calculator.h │ ├── CalculatorEx.cpp │ ├── CalculatorEx.h │ ├── MyCPP_05.vcxproj │ ├── MyCPP_05.vcxproj.filters │ ├── MyCPP_05.vcxproj.user │ └── main.cpp ├── Chapter05 ├── MyCPP_06 │ ├── MyCPP_06.sln │ └── MyCPP_06 │ │ ├── Calculator.cpp │ │ ├── Calculator.h │ │ ├── CalculatorEx.cpp │ │ ├── CalculatorEx.h │ │ ├── MyCPP_06.vcxproj │ │ ├── MyCPP_06.vcxproj.filters │ │ ├── MyCPP_06.vcxproj.user │ │ └── main.cpp └── Source │ ├── Pangaea.Target.cs │ ├── Pangaea │ ├── DefenseTower.cpp │ ├── DefenseTower.h │ ├── Pangaea.Build.cs │ ├── Pangaea.cpp │ ├── Pangaea.h │ ├── PangaeaCharacter.cpp │ ├── PangaeaCharacter.h │ ├── PangaeaGameInstance.cpp │ ├── PangaeaGameInstance.h │ ├── PangaeaGameMode.cpp │ ├── PangaeaGameMode.h │ ├── PangaeaGameState.cpp │ ├── PangaeaGameState.h │ ├── PangaeaPlayerController.cpp │ ├── PangaeaPlayerController.h │ ├── PlayerAvatar.cpp │ ├── PlayerAvatar.h │ ├── Projectile.cpp │ └── Projectile.h │ └── PangaeaEditor.Target.cs ├── Chapter06 ├── DefenseTower.cpp ├── DefenseTower.h ├── Pangaea.cpp ├── Pangaea.h ├── PangaeaCharacter.cpp ├── PangaeaCharacter.h ├── PangaeaGameInstance.cpp ├── PangaeaGameInstance.h ├── PangaeaGameMode.cpp ├── PangaeaGameMode.h ├── PangaeaGameState.cpp ├── PangaeaGameState.h ├── PangaeaPlayerController.cpp ├── PangaeaPlayerController.h ├── PlayerAvatar.cpp ├── PlayerAvatar.h ├── PlayerAvatarAnimInstance.cpp ├── PlayerAvatarAnimInstance.h ├── Projectile.cpp └── Projectile.h ├── Chapter07 ├── DefenseTower.cpp ├── DefenseTower.h ├── Enemy.cpp ├── Enemy.h ├── EnemyAnimInstance.cpp ├── EnemyAnimInstance.h ├── EnemyController.cpp ├── EnemyController.h ├── Pangaea.Build.cs ├── Pangaea.cpp ├── Pangaea.h ├── PangaeaCharacter.cpp ├── PangaeaCharacter.h ├── PangaeaGameInstance.cpp ├── PangaeaGameInstance.h ├── PangaeaGameMode.cpp ├── PangaeaGameMode.h ├── PangaeaGameState.cpp ├── PangaeaGameState.h ├── PangaeaPlayerController.cpp ├── PangaeaPlayerController.h ├── PlayerAvatar.cpp ├── PlayerAvatar.h ├── PlayerAvatarAnimInstance.cpp ├── PlayerAvatarAnimInstance.h ├── Projectile.cpp └── Projectile.h ├── Chapter08 ├── DefenseTower.cpp ├── DefenseTower.h ├── Enemy.cpp ├── Enemy.h ├── EnemyAnimInstance.cpp ├── EnemyAnimInstance.h ├── EnemyController.cpp ├── EnemyController.h ├── Pangaea.Build.cs ├── Pangaea.cpp ├── Pangaea.h ├── PangaeaCharacter.cpp ├── PangaeaCharacter.h ├── PangaeaGameInstance.cpp ├── PangaeaGameInstance.h ├── PangaeaGameMode.cpp ├── PangaeaGameMode.h ├── PangaeaGameState.cpp ├── PangaeaGameState.h ├── PangaeaPlayerController.cpp ├── PangaeaPlayerController.h ├── PlayerAvatar.cpp ├── PlayerAvatar.h ├── PlayerAvatarAnimInstance.cpp ├── PlayerAvatarAnimInstance.h ├── Projectile.cpp ├── Projectile.h ├── Weapon.cpp └── Weapon.h ├── Chapter09 ├── ActorPool.cpp ├── ActorPool.h ├── DefenseTower.cpp ├── DefenseTower.h ├── Enemy.cpp ├── Enemy.h ├── EnemyController.cpp ├── EnemyController.h ├── Pangaea.Build.cs ├── Pangaea.cpp ├── Pangaea.h ├── PangaeaAnimInstance.cpp ├── PangaeaAnimInstance.h ├── PangaeaCharacter.cpp ├── PangaeaCharacter.h ├── PangaeaGameInstance.cpp ├── PangaeaGameInstance.h ├── PangaeaGameMode.cpp ├── PangaeaGameMode.h ├── PangaeaGameState.cpp ├── PangaeaGameState.h ├── PangaeaPlayerController.cpp ├── PangaeaPlayerController.h ├── PlayerAvatar.cpp ├── PlayerAvatar.h ├── Projectile.cpp ├── Projectile.h ├── Weapon.cpp └── Weapon.h ├── Chapter10 ├── ActorPool.cpp ├── ActorPool.h ├── DefenseTower.cpp ├── DefenseTower.h ├── Enemy.cpp ├── Enemy.h ├── EnemyController.cpp ├── EnemyController.h ├── HealthBarWidget.cpp ├── HealthBarWidget.h ├── Pangaea.Build.cs ├── Pangaea.cpp ├── Pangaea.h ├── PangaeaAnimInstance.cpp ├── PangaeaAnimInstance.h ├── PangaeaCharacter.cpp ├── PangaeaCharacter.h ├── PangaeaGameInstance.cpp ├── PangaeaGameInstance.h ├── PangaeaGameMode.cpp ├── PangaeaGameMode.h ├── PangaeaGameState.cpp ├── PangaeaGameState.h ├── PangaeaPlayerController.cpp ├── PangaeaPlayerController.h ├── PlayerAvatar.cpp ├── PlayerAvatar.h ├── Projectile.cpp ├── Projectile.h ├── Weapon.cpp └── Weapon.h ├── Chapter11 ├── ActorPool.cpp ├── ActorPool.h ├── DefenseTower.cpp ├── DefenseTower.h ├── Enemy.cpp ├── Enemy.h ├── EnemyController.cpp ├── EnemyController.h ├── HealthBarWidget.cpp ├── HealthBarWidget.h ├── Pangaea.Build.cs ├── Pangaea.cpp ├── Pangaea.h ├── PangaeaAnimInstance.cpp ├── PangaeaAnimInstance.h ├── PangaeaCharacter.cpp ├── PangaeaCharacter.h ├── PangaeaGameInstance.cpp ├── PangaeaGameInstance.h ├── PangaeaGameMode.cpp ├── PangaeaGameMode.h ├── PangaeaGameState.cpp ├── PangaeaGameState.h ├── PangaeaPlayerController.cpp ├── PangaeaPlayerController.h ├── PlayerAvatar.cpp ├── PlayerAvatar.h ├── Projectile.cpp ├── Projectile.h ├── Weapon.cpp └── Weapon.h ├── Chapter12 ├── DefenseTower.cpp ├── DefenseTower.h ├── Enemy.cpp ├── Enemy.h ├── EnemyController.cpp ├── EnemyController.h ├── HealthBarWidget.cpp ├── HealthBarWidget.h ├── Pangaea.cpp ├── Pangaea.h ├── PangaeaAnimInstance.cpp ├── PangaeaAnimInstance.h ├── PangaeaCharacter.cpp ├── PangaeaCharacter.h ├── PangaeaEditor.Target.cs ├── PangaeaGameInstance.cpp ├── PangaeaGameInstance.h ├── PangaeaGameMode.cpp ├── PangaeaGameMode.h ├── PangaeaGameState.cpp ├── PangaeaGameState.h ├── PangaeaPlayerController.cpp ├── PangaeaPlayerController.h ├── PlayerAvatar.cpp ├── PlayerAvatar.h ├── Projectile.cpp ├── Projectile.h ├── Weapon.cpp └── Weapon.h ├── LICENSE ├── PangaeaAssets ├── DefenseTower │ ├── DefenseTower.FBX │ └── DefenseTower_c.TGA ├── Enemy │ ├── Enemy.FBX │ ├── T_Enemy_COL.tga │ └── T_Enemy_NOR.TGA ├── Hero │ ├── Hero.FBX │ ├── Hero_Anim_Attack.FBX │ ├── Hero_Anim_Die.FBX │ ├── Hero_Anim_Hit.FBX │ ├── Hero_Anim_Idle.FBX │ ├── Hero_Anim_Run.FBX │ ├── Hero_Anim_Walk.FBX │ ├── T_CharA_COL.TGA │ └── T_CharA_NOR.TGA ├── LobbyBG.png └── Weapons │ ├── Axe │ ├── Axe.FBX │ └── Axe_c.TGA │ ├── Hammer │ ├── Hammer.FBX │ └── hammer_c.TGA │ └── Sword │ ├── Sword.FBX │ └── Sword_c.TGA ├── README.md └── Readme.txt /.gitignore: -------------------------------------------------------------------------------- 1 | PangaeaAssets/DefenseTower/DefenseTowerASCII.FBX 2 | PangaeaAssets/Weapons/Axe/AxeASCII.FBX 3 | PangaeaAssets/Weapons/Hammer/HammerASCII.FBX 4 | PangaeaAssets/Weapons/Sword/SwordASCII.FBX 5 | -------------------------------------------------------------------------------- /Chapter02/MyCPP_01/MyCPP_01.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32929.385 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyCPP_01", "MyCPP_01\MyCPP_01.vcxproj", "{6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Debug|x64.ActiveCfg = Debug|x64 17 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Debug|x64.Build.0 = Debug|x64 18 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Debug|x86.ActiveCfg = Debug|Win32 19 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Debug|x86.Build.0 = Debug|Win32 20 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Release|x64.ActiveCfg = Release|x64 21 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Release|x64.Build.0 = Release|x64 22 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Release|x86.ActiveCfg = Release|Win32 23 | {6DCDC0A0-0D87-4DC2-BA76-4D8637AC1923}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {9CBFD318-102E-407D-876E-EA310F88E788} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Chapter02/MyCPP_01/MyCPP_01/Calculator.cpp: -------------------------------------------------------------------------------- 1 | #include "Calculator.h" 2 | 3 | float Calculator::Add(float a, float b) 4 | { 5 | float result = a + b; 6 | OutputResult(a, " + ", b, result); 7 | return result; 8 | } 9 | 10 | float Calculator::Subtract(float a, float b) 11 | { 12 | float result = a - b; 13 | OutputResult(a, " - ", b, result); 14 | return result; 15 | } 16 | 17 | void Calculator::OutputResult(float a, std::string op, float b, float result) 18 | { 19 | std::cout << "Calculator: " 20 | << a << op << b << " = " << result << "\n"; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter02/MyCPP_01/MyCPP_01/Calculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Calculator 6 | { 7 | public: 8 | float Add(float a, float b); 9 | float Subtract(float a, float b); 10 | private: 11 | void OutputResult(float, std::string, float, float); 12 | }; 13 | -------------------------------------------------------------------------------- /Chapter02/MyCPP_01/MyCPP_01/MyCPP_01.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter02/MyCPP_01/MyCPP_01/MyCPP_01.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter02/MyCPP_01/MyCPP_01/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Calculator.h" 3 | 4 | int main() 5 | { 6 | std::cout << "MyCPP_01: Hello world! \n"; 7 | 8 | Calculator Calculator; 9 | 10 | Calculator.Add(1.0f, 2.0f); 11 | Calculator.Subtract(10.0f, 5.0f); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_02/MyCPP_02.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32929.385 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyCPP_02", "MyCPP_02\MyCPP_02.vcxproj", "{51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Debug|x64.ActiveCfg = Debug|x64 17 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Debug|x64.Build.0 = Debug|x64 18 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Debug|x86.ActiveCfg = Debug|Win32 19 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Debug|x86.Build.0 = Debug|Win32 20 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Release|x64.ActiveCfg = Release|x64 21 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Release|x64.Build.0 = Release|x64 22 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Release|x86.ActiveCfg = Release|Win32 23 | {51D68B0E-4A29-4EDE-B8BC-B251F0CF9132}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {9A0B2EE1-C04C-4F5F-9780-68E5C8CA20A8} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_02/MyCPP_02/MyCPP_02.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_02/MyCPP_02/MyCPP_02.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_02/MyCPP_02/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int Add(int a, int b) 4 | { 5 | return a + b; 6 | } 7 | 8 | void main() 9 | { 10 | std::cout << "My Calculations" << std::endl; 11 | 12 | int result = Add(1, 2); 13 | std::cout << "Integer addition: 1 + 2 = " 14 | << result 15 | << std::endl; 16 | result = Add(3, 4); 17 | std::cout << "Integer addition: 3 + 4 = " 18 | << result 19 | << std::endl; 20 | 21 | std::cout << "Finished!"; 22 | } -------------------------------------------------------------------------------- /Chapter03/MyCPP_03/MyCPP_03.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32929.385 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyCPP_03", "MyCPP_03\MyCPP_03.vcxproj", "{7B71A222-243D-4C6C-879E-DDFD39F05B17}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Debug|x64.ActiveCfg = Debug|x64 17 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Debug|x64.Build.0 = Debug|x64 18 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Debug|x86.ActiveCfg = Debug|Win32 19 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Debug|x86.Build.0 = Debug|Win32 20 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Release|x64.ActiveCfg = Release|x64 21 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Release|x64.Build.0 = Release|x64 22 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Release|x86.ActiveCfg = Release|Win32 23 | {7B71A222-243D-4C6C-879E-DDFD39F05B17}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {45A289DA-3D30-489D-BED3-753251F35522} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_03/MyCPP_03/Calculator.cpp: -------------------------------------------------------------------------------- 1 | #include "Calculator.h" 2 | 3 | int Add(int a, int b) 4 | { 5 | return a + b; 6 | } 7 | 8 | float Add(float a, float b) 9 | { 10 | return a + b; 11 | } -------------------------------------------------------------------------------- /Chapter03/MyCPP_03/MyCPP_03/Calculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | Function Add: adds two integers and returns the result 5 | Parameters a, b: the two integer input values 6 | */ 7 | int Add(int a, int b); 8 | 9 | /* 10 | Function Add: adds two floats and returns the result 11 | Parameters a, b: the two float input values 12 | */ 13 | float Add(float a, float b); 14 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_03/MyCPP_03/MyCPP_03.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_03/MyCPP_03/MyCPP_03.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_03/MyCPP_03/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Calculator.h" 3 | 4 | using namespace std; 5 | 6 | void main() 7 | { 8 | cout << "My Calculations" << endl; 9 | 10 | float input1, input2; 11 | while (true) 12 | { 13 | cout << "Input the first value (0 to exit): "; 14 | cin >> input1; 15 | if (input1 == 0) //exit if the user enters 0 16 | { 17 | break; 18 | } 19 | cout << "Input the second value (0 to exit): "; 20 | cin >> input2; 21 | if (input2 == 0) //exit if the user enters 0 22 | { 23 | break; 24 | } 25 | 26 | int a = input1; 27 | int b = input2; 28 | if (a == input1 && b == input2) 29 | { 30 | int result = Add(a, b); 31 | cout << "Integer addition: " << a << " + " << b << " = " 32 | << result 33 | << std::endl; 34 | } 35 | else 36 | { 37 | float result = Add(input1, input2); 38 | cout << "float addition: " << input1 << " + " << input2 << " = " 39 | << result 40 | << std::endl; 41 | } 42 | } 43 | std::cout << "Finished!"; 44 | } 45 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32929.385 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyCPP_04", "MyCPP_04\MyCPP_04.vcxproj", "{5DE2BE58-E525-436C-BDFD-0319D738F462}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Debug|x64.ActiveCfg = Debug|x64 17 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Debug|x64.Build.0 = Debug|x64 18 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Debug|x86.ActiveCfg = Debug|Win32 19 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Debug|x86.Build.0 = Debug|Win32 20 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Release|x64.ActiveCfg = Release|x64 21 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Release|x64.Build.0 = Release|x64 22 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Release|x86.ActiveCfg = Release|Win32 23 | {5DE2BE58-E525-436C-BDFD-0319D738F462}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {3CC58A4B-AFB7-4C78-8008-3D5BE5440851} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04/Calculator.cpp: -------------------------------------------------------------------------------- 1 | #include "Calculator.h" 2 | 3 | Calculator::Calculator() 4 | { 5 | _name = "Addition Calculator"; 6 | } 7 | 8 | string Calculator::GetName() 9 | { 10 | return _name; 11 | } 12 | 13 | int Calculator::Add(int a, int b) 14 | { 15 | return a + b; 16 | } 17 | 18 | float Calculator::Add(float a, float b) 19 | { 20 | return a + b; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04/Calculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Calculator 8 | { 9 | protected: 10 | 11 | string _name; 12 | 13 | public: 14 | Calculator(); //This is the constructor 15 | 16 | string GetName(); 17 | 18 | /* 19 | Function Add: adds two integers and returns the result 20 | Parameters a, b: the two integer input values 21 | */ 22 | int Add(int a, int b); 23 | 24 | /* 25 | Function Add: adds two floats and returns the result 26 | Parameters a, b: the two float input values 27 | */ 28 | float Add(float a, float b); 29 | }; -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04/CalculatorEx.cpp: -------------------------------------------------------------------------------- 1 | #include "CalculatorEx.h" 2 | 3 | CalculatorEx::CalculatorEx() 4 | { 5 | _name = "Advanced Calculator"; 6 | } 7 | 8 | int CalculatorEx::Subtract(int a, int b) 9 | { 10 | return a - b; 11 | } 12 | 13 | float CalculatorEx::Subtract(float a, float b) 14 | { 15 | return a - b; 16 | } -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04/CalculatorEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Calculator.h" 4 | 5 | class CalculatorEx : public Calculator 6 | { 7 | public: 8 | 9 | CalculatorEx(); //This is the constructor 10 | 11 | int Subtract(int a, int b); 12 | 13 | float Subtract(float a, float b); 14 | }; -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04/MyCPP_04.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04/MyCPP_04.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_04/MyCPP_04/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Calculator.h" 3 | 4 | using namespace std; 5 | 6 | void main() 7 | { 8 | Calculator calculator; //defines the calculator object 9 | cout << "My Calculations: " << calculator.GetName() << endl; 10 | 11 | float input1, input2; 12 | while (true) 13 | { 14 | cout << "Input the first value (0 to exit): "; 15 | cin >> input1; 16 | if (input1 == 0) //exit if the user enters 0 17 | { 18 | break; 19 | } 20 | 21 | cout << "Input the second value (0 to exit): "; 22 | cin >> input2; 23 | if (input2 == 0) //exit if the user enters 0 24 | { 25 | break; 26 | } 27 | 28 | int a = input1; 29 | int b = input2; 30 | if (a == input1 && b == input2) 31 | { 32 | int result = calculator.Add(a, b); 33 | cout << "Integer addition: " << a << " + " << b << " = " 34 | << result 35 | << std::endl; 36 | } 37 | else 38 | { 39 | float result = calculator.Add(input1, input2); 40 | cout << "float addition: " << input1 << " + " << input2 << " = " 41 | << result 42 | << std::endl; 43 | } 44 | } 45 | 46 | std::cout << "Finished!"; 47 | } 48 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32929.385 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyCPP_05", "MyCPP_05\MyCPP_05.vcxproj", "{F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x64.ActiveCfg = Debug|x64 17 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x64.Build.0 = Debug|x64 18 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x86.ActiveCfg = Debug|Win32 19 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x86.Build.0 = Debug|Win32 20 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x64.ActiveCfg = Release|x64 21 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x64.Build.0 = Release|x64 22 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x86.ActiveCfg = Release|Win32 23 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {55613F88-5889-4D16-A743-A49B9DD3ACB0} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05/Calculator.cpp: -------------------------------------------------------------------------------- 1 | #include "Calculator.h" 2 | 3 | Calculator::Calculator() 4 | { 5 | _name = "Addition Calculator"; 6 | } 7 | 8 | string Calculator::GetName() 9 | { 10 | return _name; 11 | } 12 | 13 | int Calculator::Add(int a, int b) 14 | { 15 | return a + b; 16 | } 17 | 18 | float Calculator::Add(float a, float b) 19 | { 20 | return a + b; 21 | } 22 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05/Calculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Calculator 8 | { 9 | protected: 10 | 11 | string _name; 12 | 13 | public: 14 | Calculator(); //This is the constructor 15 | 16 | string GetName(); 17 | 18 | /* 19 | Function Add: adds two integers and returns the result 20 | Parameters a, b: the two integer input values 21 | */ 22 | int Add(int a, int b); 23 | 24 | /* 25 | Function Add: adds two floats and returns the result 26 | Parameters a, b: the two float input values 27 | */ 28 | float Add(float a, float b); 29 | }; -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05/CalculatorEx.cpp: -------------------------------------------------------------------------------- 1 | #include "CalculatorEx.h" 2 | 3 | CalculatorEx::CalculatorEx() 4 | { 5 | _name = "Advanced Calculator"; 6 | } 7 | 8 | int CalculatorEx::Subtract(int a, int b) 9 | { 10 | return a - b; 11 | } 12 | 13 | float CalculatorEx::Subtract(float a, float b) 14 | { 15 | return a - b; 16 | } -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05/CalculatorEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Calculator.h" 4 | 5 | class CalculatorEx : public Calculator 6 | { 7 | public: 8 | 9 | CalculatorEx(); //This is the constructor 10 | 11 | int Subtract(int a, int b); 12 | 13 | float Subtract(float a, float b); 14 | }; -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05/MyCPP_05.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05/MyCPP_05.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter03/MyCPP_05/MyCPP_05/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Calculator.h" 3 | #include "CalculatorEx.h" 4 | 5 | using namespace std; 6 | 7 | void main() 8 | { 9 | //CalculatorEx calculator; //defines the calculator object 10 | CalculatorEx *pCalculator = new CalculatorEx(); 11 | //creates a new CalculatorEx instance and 12 | //store its address to the pCalculator pointer 13 | 14 | //cout << "My Calculations: " << calculator.GetName() << endl; 15 | cout << "My Calculations: " << pCalculator->GetName() << endl; 16 | 17 | float input1, input2; 18 | string operation; 19 | while (true) 20 | { 21 | cout << "Input the first value (0 to exit): "; 22 | cin >> input1; 23 | if (input1 == 0) //exit if the user enters 0 24 | { 25 | break; 26 | } 27 | 28 | cout << "Input the second value (0 to exit): "; 29 | cin >> input2; 30 | if (input2 == 0) //exit if the user enters 0 31 | { 32 | break; 33 | } 34 | 35 | operation = "+"; 36 | do 37 | { 38 | cout << "Please choose the operation (+ or -): "; 39 | cin >> operation; 40 | } while (operation != "+" && operation != "-"); 41 | 42 | int a = input1; 43 | int b = input2; 44 | if (a == input1 && b == input2) 45 | { 46 | int result; 47 | if (operation == "+") 48 | { 49 | //result = calculator.Add(a, b); 50 | result = pCalculator->Add(a, b); 51 | cout << "Integer addition: " << a << " + " << b << " = " 52 | << result 53 | << std::endl; 54 | } 55 | else 56 | { 57 | //result = calculator.Subtract(a, b); 58 | result = pCalculator->Subtract(a, b); 59 | cout << "Integer subtraction: " << a << " - " << b << " = " 60 | << result 61 | << std::endl; 62 | } 63 | } 64 | else 65 | { 66 | float result; 67 | if (operation == "+") 68 | { 69 | //result = calculator.Add(input1, input2); 70 | result = pCalculator->Add(input1, input2); 71 | cout << "float addition: " << input1 << " + " << input2 << " = " 72 | << result 73 | << std::endl; 74 | } 75 | else 76 | { 77 | //result = calculator.Subtract(input1, input2); 78 | result = pCalculator->Subtract(input1, input2); 79 | cout << "float subtraction: " << input1 << " - " << input2 << " = " 80 | << result 81 | << std::endl; 82 | } 83 | } 84 | } 85 | 86 | delete pCalculator; 87 | std::cout << "Finished!"; 88 | } 89 | -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.3.32929.385 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyCPP_06", "MyCPP_06\MyCPP_06.vcxproj", "{F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x64.ActiveCfg = Debug|x64 17 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x64.Build.0 = Debug|x64 18 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x86.ActiveCfg = Debug|Win32 19 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Debug|x86.Build.0 = Debug|Win32 20 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x64.ActiveCfg = Release|x64 21 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x64.Build.0 = Release|x64 22 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x86.ActiveCfg = Release|Win32 23 | {F75ECB2D-1A70-4F89-9C1C-4DA15ABBCB94}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {55613F88-5889-4D16-A743-A49B9DD3ACB0} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06/Calculator.cpp: -------------------------------------------------------------------------------- 1 | #include "Calculator.h" 2 | 3 | Calculator::Calculator() 4 | { 5 | _name = "Addition Calculator"; 6 | } 7 | 8 | string Calculator::GetName() 9 | { 10 | return _name; 11 | } 12 | -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06/Calculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Calculator 8 | { 9 | protected: 10 | 11 | string _name; 12 | 13 | public: 14 | Calculator(); //This is the constructor 15 | 16 | string GetName(); 17 | 18 | 19 | /* 20 | Function Add: adds two values and returns the result 21 | Parameters a, b: the two input values 22 | */ 23 | template 24 | T Add(T a, T b) 25 | { 26 | return a + b; 27 | } 28 | }; -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06/CalculatorEx.cpp: -------------------------------------------------------------------------------- 1 | #include "CalculatorEx.h" 2 | 3 | CalculatorEx::CalculatorEx() 4 | { 5 | _name = "Advanced Calculator"; 6 | } 7 | 8 | -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06/CalculatorEx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Calculator.h" 4 | 5 | class CalculatorEx : public Calculator 6 | { 7 | public: 8 | 9 | CalculatorEx(); //This is the constructor 10 | 11 | template 12 | T Subtract(T a, T b) 13 | { 14 | return a - b; 15 | } 16 | }; -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06/MyCPP_06.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06/MyCPP_06.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Chapter05/MyCPP_06/MyCPP_06/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Calculator.h" 3 | #include "CalculatorEx.h" 4 | 5 | using namespace std; 6 | 7 | void main() 8 | { 9 | //CalculatorEx calculator; //defines the calculator object 10 | CalculatorEx *pCalculator = new CalculatorEx(); 11 | //creates a new CalculatorEx instance and 12 | //store its address to the pCalculator pointer 13 | 14 | //cout << "My Calculations: " << calculator.GetName() << endl; 15 | cout << "My Calculations: " << pCalculator->GetName() << endl; 16 | 17 | float input1, input2; 18 | string operation; 19 | while (true) 20 | { 21 | cout << "Input the first value (0 to exit): "; 22 | cin >> input1; 23 | if (input1 == 0) //exit if the user enters 0 24 | { 25 | break; 26 | } 27 | 28 | cout << "Input the second value (0 to exit): "; 29 | cin >> input2; 30 | if (input1 == 0) //exit if the user enters 0 31 | { 32 | break; 33 | } 34 | 35 | operation = "+"; 36 | do 37 | { 38 | cout << "Please choose the operation (+ or -): "; 39 | cin >> operation; 40 | } while (operation != "+" && operation != "-"); 41 | 42 | int a = input1; 43 | int b = input2; 44 | if (a == input1 && b == input2) 45 | { 46 | int result; 47 | if (operation == "+") 48 | { 49 | //result = calculator.Add(a, b); 50 | result = pCalculator->Add(a, b); 51 | cout << "Integer addition: " << a << " + " << b << " = " 52 | << result 53 | << std::endl; 54 | } 55 | else 56 | { 57 | //result = calculator.Subtract(a, b); 58 | result = pCalculator->Subtract(a, b); 59 | cout << "Integer subtraction: " << a << " - " << b << " = " 60 | << result 61 | << std::endl; 62 | } 63 | } 64 | else 65 | { 66 | float result; 67 | if (operation == "+") 68 | { 69 | //result = calculator.Add(input1, input2); 70 | result = pCalculator->Add(input1, input2); 71 | cout << "float addition: " << input1 << " + " << input2 << " = " 72 | << result 73 | << std::endl; 74 | } 75 | else 76 | { 77 | //result = calculator.Subtract(input1, input2); 78 | result = pCalculator->Subtract(input1, input2); 79 | cout << "float subtraction: " << input1 << " - " << input2 << " = " 80 | << result 81 | << std::endl; 82 | } 83 | } 84 | } 85 | 86 | delete pCalculator; 87 | std::cout << "Finished!"; 88 | } 89 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class PangaeaTarget : TargetRules 7 | { 8 | public PangaeaTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Game; 11 | DefaultBuildSettings = BuildSettingsVersion.V2; 12 | ExtraModuleNames.Add("Pangaea"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/DefenseTower.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "DefenseTower.h" 5 | 6 | // Sets default values 7 | ADefenseTower::ADefenseTower() 8 | { 9 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 10 | PrimaryActorTick.bCanEverTick = true; 11 | 12 | _BoxComponent = CreateDefaultSubobject(TEXT("Box Collision")); 13 | SetRootComponent(_BoxComponent); 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | _MeshComponent->SetupAttachment(_BoxComponent); 17 | } 18 | 19 | // Called when the game starts or when spawned 20 | void ADefenseTower::BeginPlay() 21 | { 22 | Super::BeginPlay(); 23 | 24 | } 25 | 26 | // Called every frame 27 | void ADefenseTower::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | } 32 | 33 | int ADefenseTower::GetHealthPoints() 34 | { 35 | return _HealthPoints; 36 | } 37 | 38 | bool ADefenseTower::IsDestroyed() 39 | { 40 | return (_HealthPoints > 0.0f); 41 | } 42 | 43 | bool ADefenseTower::CanFire() 44 | { 45 | return (_ReloadCountingDown <= 0.0f); 46 | } 47 | 48 | void ADefenseTower::Fire() 49 | { 50 | } 51 | 52 | 53 | void ADefenseTower::Hit(int damage) 54 | { 55 | } 56 | 57 | void ADefenseTower::DestroyProcess() 58 | { 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/Pangaea.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class Pangaea : ModuleRules 6 | { 7 | public Pangaea(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "NavigationSystem", "AIModule", "Niagara" }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaCharacter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaCharacter.h" 4 | #include "UObject/ConstructorHelpers.h" 5 | #include "Camera/CameraComponent.h" 6 | #include "Components/DecalComponent.h" 7 | #include "Components/CapsuleComponent.h" 8 | #include "GameFramework/CharacterMovementComponent.h" 9 | #include "GameFramework/PlayerController.h" 10 | #include "GameFramework/SpringArmComponent.h" 11 | #include "Materials/Material.h" 12 | #include "Engine/World.h" 13 | 14 | APangaeaCharacter::APangaeaCharacter() 15 | { 16 | // Set size for player capsule 17 | GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); 18 | 19 | // Don't rotate character to camera direction 20 | bUseControllerRotationPitch = false; 21 | bUseControllerRotationYaw = false; 22 | bUseControllerRotationRoll = false; 23 | 24 | // Configure character movement 25 | GetCharacterMovement()->bOrientRotationToMovement = true; // Rotate character to moving direction 26 | GetCharacterMovement()->RotationRate = FRotator(0.f, 640.f, 0.f); 27 | GetCharacterMovement()->bConstrainToPlane = true; 28 | GetCharacterMovement()->bSnapToPlaneAtStart = true; 29 | 30 | // Create a camera boom... 31 | CameraBoom = CreateDefaultSubobject(TEXT("CameraBoom")); 32 | CameraBoom->SetupAttachment(RootComponent); 33 | CameraBoom->SetUsingAbsoluteRotation(true); // Don't want arm to rotate when character does 34 | CameraBoom->TargetArmLength = 800.f; 35 | CameraBoom->SetRelativeRotation(FRotator(-60.f, 0.f, 0.f)); 36 | CameraBoom->bDoCollisionTest = false; // Don't want to pull camera in when it collides with level 37 | 38 | // Create a camera... 39 | TopDownCameraComponent = CreateDefaultSubobject(TEXT("TopDownCamera")); 40 | TopDownCameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); 41 | TopDownCameraComponent->bUsePawnControlRotation = false; // Camera does not rotate relative to arm 42 | 43 | // Activate ticking in order to update the cursor every frame. 44 | PrimaryActorTick.bCanEverTick = true; 45 | PrimaryActorTick.bStartWithTickEnabled = true; 46 | } 47 | 48 | void APangaeaCharacter::Tick(float DeltaSeconds) 49 | { 50 | Super::Tick(DeltaSeconds); 51 | } 52 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Character.h" 7 | #include "PangaeaCharacter.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class APangaeaCharacter : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaCharacter(); 16 | 17 | // Called every frame. 18 | virtual void Tick(float DeltaSeconds) override; 19 | 20 | /** Returns TopDownCameraComponent subobject **/ 21 | FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; } 22 | /** Returns CameraBoom subobject **/ 23 | FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; } 24 | 25 | private: 26 | /** Top down camera */ 27 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 28 | class UCameraComponent* TopDownCameraComponent; 29 | 30 | /** Camera boom positioning the camera above the character */ 31 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 32 | class USpringArmComponent* CameraBoom; 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameInstance.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/GameInstance.h" 7 | #include "PangaeaGameInstance.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaGameMode.h" 4 | #include "PangaeaPlayerController.h" 5 | #include "PangaeaCharacter.h" 6 | #include "UObject/ConstructorHelpers.h" 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownCharacter")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if(PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameModeBase.h" 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | }; 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameState.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameStateBase.h" 7 | #include "PangaeaGameState.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API APangaeaGameState : public AGameStateBase 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | private: 45 | bool bInputPressed; // Input is bring pressed 46 | bool bIsTouch; // Is it a touch device 47 | float FollowTime; // For how long it has been pressed 48 | }; 49 | 50 | 51 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PlayerAvatar.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PlayerAvatar.h" 5 | 6 | // Sets default values 7 | APlayerAvatar::APlayerAvatar() 8 | { 9 | // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it. 10 | PrimaryActorTick.bCanEverTick = true; 11 | 12 | } 13 | 14 | // Called when the game starts or when spawned 15 | void APlayerAvatar::BeginPlay() 16 | { 17 | Super::BeginPlay(); 18 | 19 | } 20 | 21 | // Called every frame 22 | void APlayerAvatar::Tick(float DeltaTime) 23 | { 24 | Super::Tick(DeltaTime); 25 | 26 | } 27 | 28 | // Called to bind functionality to input 29 | void APlayerAvatar::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) 30 | { 31 | Super::SetupPlayerInputComponent(PlayerInputComponent); 32 | 33 | } 34 | 35 | int APlayerAvatar::GetHealthPoints() 36 | { 37 | return _HealthPoints; 38 | } 39 | 40 | 41 | bool APlayerAvatar::IsKilled() 42 | { 43 | return (_HealthPoints <= 0.0f); 44 | } 45 | 46 | 47 | bool APlayerAvatar::CanAttack() 48 | { 49 | return (_AttackCountingDown <= 0.0f); 50 | } 51 | 52 | 53 | void APlayerAvatar::Attack() 54 | { 55 | 56 | } 57 | 58 | void APlayerAvatar::Hit(int damage) 59 | { 60 | 61 | } -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/PlayerAvatar.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Character.h" 7 | #include "PlayerAvatar.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class PANGAEA_API APlayerAvatar : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | // Sets default values for this character's properties 16 | APlayerAvatar(); 17 | 18 | UPROPERTY(EditAnywhere, Category = "PlayerAvatar Params") 19 | int HealthPoints = 500; //the character's max health points 20 | 21 | UPROPERTY(EditAnywhere, Category = "PlayerAvatar Params") 22 | float Strength = 10; //the character's attack strength 23 | 24 | UPROPERTY(EditAnywhere, Category = "PlayerAvatar Params") 25 | float Armor = 3.0f; //the character's defense armer 26 | 27 | UPROPERTY(EditAnywhere, Category = "PlayerAvatar Params") 28 | float AttackRange = 6.0f; //the character's attack range 29 | 30 | UPROPERTY(EditAnywhere, Category = "PlayerAvatar Params") 31 | float AttackInterval = 1.2f; //the character's attack invertal 32 | protected: 33 | // Called when the game starts or when spawned 34 | virtual void BeginPlay() override; 35 | 36 | int _HealthPoints; 37 | float _AttackCountingDown; 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | 42 | // Called to bind functionality to input 43 | virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; 44 | 45 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerCharacter", meta = (DisplayName = "Get HP")) 46 | int GetHealthPoints(); //get current health points 47 | 48 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerCharacter") 49 | bool IsKilled(); //check if the character has been killed 50 | 51 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerCharacter") 52 | bool CanAttack(); //check if the character can attack 53 | 54 | void Attack(); //attack 55 | void Hit(int damage); //process when the character is hit 56 | 57 | protected: 58 | void DieProcess(); //process when the character is killed 59 | }; 60 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/Projectile.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "Projectile.h" 5 | 6 | // Sets default values 7 | AProjectile::AProjectile() 8 | { 9 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 10 | PrimaryActorTick.bCanEverTick = true; 11 | 12 | _BoxComponent = CreateDefaultSubobject(TEXT("Box Collision")); 13 | SetRootComponent(_BoxComponent); 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | _MeshComponent->SetupAttachment(_BoxComponent); 17 | } 18 | 19 | // Called when the game starts or when spawned 20 | void AProjectile::BeginPlay() 21 | { 22 | Super::BeginPlay(); 23 | 24 | } 25 | 26 | // Called every frame 27 | void AProjectile::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Chapter05/Source/Pangaea/Projectile.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "Components/BoxComponent.h" 8 | #include "Components/StaticMeshComponent.h" 9 | #include "Projectile.generated.h" 10 | 11 | UCLASS(Blueprintable) 12 | class PANGAEA_API AProjectile : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AProjectile(); 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Speed = 100.0f; //the projectile's speed 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Lifespan = 5.0f; //the projectile's lifespan 25 | 26 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 27 | float Damage = 10.0f; //the projectile's damage points 28 | 29 | protected: 30 | // Called when the game starts or when spawned 31 | virtual void BeginPlay() override; 32 | 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 34 | UBoxComponent* _BoxComponent; 35 | 36 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 37 | UStaticMeshComponent* _MeshComponent; 38 | 39 | float _LifeCountingDown; 40 | public: 41 | // Called every frame 42 | virtual void Tick(float DeltaTime) override; 43 | 44 | FORCEINLINE UBoxComponent* GetBoxComponent() const { return _BoxComponent; } 45 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 46 | }; 47 | -------------------------------------------------------------------------------- /Chapter05/Source/PangaeaEditor.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class PangaeaEditorTarget : TargetRules 7 | { 8 | public PangaeaEditorTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Editor; 11 | DefaultBuildSettings = BuildSettingsVersion.V2; 12 | ExtraModuleNames.Add("Pangaea"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter06/DefenseTower.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "DefenseTower.h" 5 | 6 | // Sets default values 7 | ADefenseTower::ADefenseTower() 8 | { 9 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 10 | PrimaryActorTick.bCanEverTick = true; 11 | 12 | _BoxComponent = CreateDefaultSubobject(TEXT("Box Collision")); 13 | SetRootComponent(_BoxComponent); 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | _MeshComponent->SetupAttachment(_BoxComponent); 17 | } 18 | 19 | // Called when the game starts or when spawned 20 | void ADefenseTower::BeginPlay() 21 | { 22 | Super::BeginPlay(); 23 | 24 | } 25 | 26 | // Called every frame 27 | void ADefenseTower::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | } 32 | 33 | int ADefenseTower::GetHealthPoints() 34 | { 35 | return _HealthPoints; 36 | } 37 | 38 | bool ADefenseTower::IsDestroyed() 39 | { 40 | return (_HealthPoints > 0.0f); 41 | } 42 | 43 | bool ADefenseTower::CanFire() 44 | { 45 | return (_ReloadCountingDown <= 0.0f); 46 | } 47 | 48 | void ADefenseTower::Fire() 49 | { 50 | } 51 | 52 | 53 | void ADefenseTower::Hit(int damage) 54 | { 55 | } 56 | 57 | void ADefenseTower::DestroyProcess() 58 | { 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Chapter06/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter06/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter06/PangaeaCharacter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaCharacter.h" 4 | #include "UObject/ConstructorHelpers.h" 5 | #include "Camera/CameraComponent.h" 6 | #include "Components/DecalComponent.h" 7 | #include "Components/CapsuleComponent.h" 8 | #include "GameFramework/CharacterMovementComponent.h" 9 | #include "GameFramework/PlayerController.h" 10 | #include "GameFramework/SpringArmComponent.h" 11 | #include "Materials/Material.h" 12 | #include "Engine/World.h" 13 | 14 | APangaeaCharacter::APangaeaCharacter() 15 | { 16 | // Set size for player capsule 17 | GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); 18 | 19 | // Don't rotate character to camera direction 20 | bUseControllerRotationPitch = false; 21 | bUseControllerRotationYaw = false; 22 | bUseControllerRotationRoll = false; 23 | 24 | // Configure character movement 25 | GetCharacterMovement()->bOrientRotationToMovement = true; // Rotate character to moving direction 26 | GetCharacterMovement()->RotationRate = FRotator(0.f, 640.f, 0.f); 27 | GetCharacterMovement()->bConstrainToPlane = true; 28 | GetCharacterMovement()->bSnapToPlaneAtStart = true; 29 | 30 | // Create a camera boom... 31 | CameraBoom = CreateDefaultSubobject(TEXT("CameraBoom")); 32 | CameraBoom->SetupAttachment(RootComponent); 33 | CameraBoom->SetUsingAbsoluteRotation(true); // Don't want arm to rotate when character does 34 | CameraBoom->TargetArmLength = 800.f; 35 | CameraBoom->SetRelativeRotation(FRotator(-60.f, 0.f, 0.f)); 36 | CameraBoom->bDoCollisionTest = false; // Don't want to pull camera in when it collides with level 37 | 38 | // Create a camera... 39 | TopDownCameraComponent = CreateDefaultSubobject(TEXT("TopDownCamera")); 40 | TopDownCameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); 41 | TopDownCameraComponent->bUsePawnControlRotation = false; // Camera does not rotate relative to arm 42 | 43 | // Activate ticking in order to update the cursor every frame. 44 | PrimaryActorTick.bCanEverTick = true; 45 | PrimaryActorTick.bStartWithTickEnabled = true; 46 | } 47 | 48 | void APangaeaCharacter::Tick(float DeltaSeconds) 49 | { 50 | Super::Tick(DeltaSeconds); 51 | } 52 | -------------------------------------------------------------------------------- /Chapter06/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Character.h" 7 | #include "PangaeaCharacter.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class APangaeaCharacter : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaCharacter(); 16 | 17 | // Called every frame. 18 | virtual void Tick(float DeltaSeconds) override; 19 | 20 | /** Returns TopDownCameraComponent subobject **/ 21 | FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; } 22 | /** Returns CameraBoom subobject **/ 23 | FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; } 24 | 25 | private: 26 | /** Top down camera */ 27 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 28 | class UCameraComponent* TopDownCameraComponent; 29 | 30 | /** Camera boom positioning the camera above the character */ 31 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 32 | class USpringArmComponent* CameraBoom; 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /Chapter06/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameInstance.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter06/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/GameInstance.h" 7 | #include "PangaeaGameInstance.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter06/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaGameMode.h" 4 | #include "PangaeaPlayerController.h" 5 | #include "PangaeaCharacter.h" 6 | #include "UObject/ConstructorHelpers.h" 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_PlayerAvatar")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if(PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter06/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameModeBase.h" 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | }; 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter06/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameState.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter06/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameStateBase.h" 7 | #include "PangaeaGameState.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API APangaeaGameState : public AGameStateBase 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter06/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | private: 45 | bool bInputPressed; // Input is bring pressed 46 | bool bIsTouch; // Is it a touch device 47 | float FollowTime; // For how long it has been pressed 48 | }; 49 | 50 | 51 | -------------------------------------------------------------------------------- /Chapter06/PlayerAvatarAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PlayerAvatarAnimInstance.h" 5 | #include "PlayerAvatar.h" 6 | 7 | void UPlayerAvatarAnimInstance::OnStateAnimationEnds() 8 | { 9 | if (State == EPlayerState::Attack) 10 | { 11 | State = EPlayerState::Locomotion; 12 | } 13 | else 14 | { 15 | auto ownerActor = this->GetOwningActor(); 16 | auto playerAvatar = Cast(ownerActor); 17 | 18 | if (playerAvatar == nullptr) 19 | { 20 | UE_LOG(LogAnimation, Error, TEXT("The owner actor is not a PlayerAvatar!")); 21 | return; 22 | } 23 | 24 | if (State == EPlayerState::Hit) 25 | { 26 | if (playerAvatar->GetHealthPoints() > 0.0f) 27 | { 28 | State = EPlayerState::Locomotion; 29 | } 30 | else 31 | { 32 | State = EPlayerState::Die; 33 | } 34 | 35 | } 36 | else if (State == EPlayerState::Die) 37 | { 38 | //... 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Chapter06/PlayerAvatarAnimInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Animation/AnimInstance.h" 7 | #include "PlayerAvatarAnimInstance.generated.h" 8 | 9 | UENUM(BlueprintType) 10 | enum class EPlayerState : uint8 11 | { 12 | Locomotion, 13 | Attack, 14 | Hit, 15 | Die 16 | }; 17 | 18 | 19 | /** 20 | * 21 | */ 22 | UCLASS() 23 | class PANGAEA_API UPlayerAvatarAnimInstance : public UAnimInstance 24 | { 25 | GENERATED_BODY() 26 | 27 | 28 | public : 29 | 30 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Avatar Params") 31 | float Speed; 32 | 33 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Avatar Params") 34 | EPlayerState State; 35 | 36 | UFUNCTION(BlueprintCallable) 37 | void OnStateAnimationEnds(); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /Chapter06/Projectile.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "Projectile.h" 5 | 6 | // Sets default values 7 | AProjectile::AProjectile() 8 | { 9 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 10 | PrimaryActorTick.bCanEverTick = true; 11 | 12 | _BoxComponent = CreateDefaultSubobject(TEXT("Box Collision")); 13 | SetRootComponent(_BoxComponent); 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | _MeshComponent->SetupAttachment(_BoxComponent); 17 | } 18 | 19 | // Called when the game starts or when spawned 20 | void AProjectile::BeginPlay() 21 | { 22 | Super::BeginPlay(); 23 | 24 | } 25 | 26 | // Called every frame 27 | void AProjectile::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Chapter06/Projectile.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "Components/BoxComponent.h" 8 | #include "Components/StaticMeshComponent.h" 9 | #include "Projectile.generated.h" 10 | 11 | UCLASS(Blueprintable) 12 | class PANGAEA_API AProjectile : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AProjectile(); 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Speed = 100.0f; //the projectile's speed 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Lifespan = 5.0f; //the projectile's lifespan 25 | 26 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 27 | float Damage = 10.0f; //the projectile's damage points 28 | 29 | protected: 30 | // Called when the game starts or when spawned 31 | virtual void BeginPlay() override; 32 | 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 34 | UBoxComponent* _BoxComponent; 35 | 36 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 37 | UStaticMeshComponent* _MeshComponent; 38 | 39 | float _LifeCountingDown; 40 | public: 41 | // Called every frame 42 | virtual void Tick(float DeltaTime) override; 43 | 44 | FORCEINLINE UBoxComponent* GetBoxComponent() const { return _BoxComponent; } 45 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 46 | }; 47 | -------------------------------------------------------------------------------- /Chapter07/DefenseTower.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "DefenseTower.h" 5 | 6 | // Sets default values 7 | ADefenseTower::ADefenseTower() 8 | { 9 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 10 | PrimaryActorTick.bCanEverTick = true; 11 | 12 | _BoxComponent = CreateDefaultSubobject(TEXT("Box Collision")); 13 | SetRootComponent(_BoxComponent); 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | _MeshComponent->SetupAttachment(_BoxComponent); 17 | } 18 | 19 | // Called when the game starts or when spawned 20 | void ADefenseTower::BeginPlay() 21 | { 22 | Super::BeginPlay(); 23 | 24 | } 25 | 26 | // Called every frame 27 | void ADefenseTower::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | } 32 | 33 | int ADefenseTower::GetHealthPoints() 34 | { 35 | return _HealthPoints; 36 | } 37 | 38 | bool ADefenseTower::IsDestroyed() 39 | { 40 | return (_HealthPoints > 0.0f); 41 | } 42 | 43 | bool ADefenseTower::CanFire() 44 | { 45 | return (_ReloadCountingDown <= 0.0f); 46 | } 47 | 48 | void ADefenseTower::Fire() 49 | { 50 | } 51 | 52 | 53 | void ADefenseTower::Hit(int damage) 54 | { 55 | } 56 | 57 | void ADefenseTower::DestroyProcess() 58 | { 59 | 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Chapter07/Enemy.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Character.h" 7 | #include "Enemy.generated.h" 8 | 9 | UCLASS() 10 | class PANGAEA_API AEnemy : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | // Sets default values for this character's properties 16 | AEnemy(); 17 | 18 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 19 | int HealthPoints = 100; //the character's max health points 20 | 21 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 22 | float Strength = 5; //the character's attack strength 23 | 24 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 25 | float Armer = 1; //the character's defense armer 26 | 27 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 28 | float AttackRange = 200.0f; //the character's attack range 29 | 30 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 31 | float AttackInterval = 3.0f; //the character's attack invertal 32 | 33 | protected: 34 | // Called when the game starts or when spawned 35 | virtual void BeginPlay() override; 36 | 37 | int _HealthPoints; 38 | float _AttackCountingDown; 39 | APawn* _chasedTarget = nullptr; 40 | 41 | public: 42 | // Called every frame 43 | virtual void Tick(float DeltaTime) override; 44 | 45 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy", meta = (DisplayName = "Get HP")) 46 | int GetHealthPoints(); //get current health points 47 | 48 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 49 | bool IsKilled(); //check if the character has been killed 50 | 51 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 52 | bool CanAttack(); //check if the character can attack 53 | 54 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 55 | void Chase(APawn* targetPawn); 56 | 57 | void Attack(); 58 | void Hit(int damage); 59 | void DieProcess(); //process when the character is killed 60 | 61 | private: 62 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 63 | class UPawnSensingComponent* PawnSensingComponent; 64 | }; 65 | -------------------------------------------------------------------------------- /Chapter07/EnemyAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "EnemyAnimInstance.h" 5 | #include "Enemy.h" 6 | 7 | void UEnemyAnimInstance::OnStateAnimationEnds() 8 | { 9 | if (State == EEnemyState::Attack) 10 | { 11 | State = EEnemyState::Locomotion; 12 | } 13 | else 14 | { 15 | auto enemy = Cast(GetOwningActor()); 16 | 17 | if (State == EEnemyState::Hit) 18 | { 19 | if (enemy->GetHealthPoints() > 0.0f) 20 | { 21 | State = EEnemyState::Locomotion; 22 | } 23 | else 24 | { 25 | State = EEnemyState::Die; 26 | } 27 | 28 | } 29 | else if (State == EEnemyState::Die) 30 | { 31 | enemy->DieProcess(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter07/EnemyAnimInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Animation/AnimInstance.h" 7 | #include "EnemyAnimInstance.generated.h" 8 | 9 | UENUM(BlueprintType) 10 | enum class EEnemyState : uint8 11 | { 12 | Locomotion, 13 | Attack, 14 | Hit, 15 | Die 16 | }; 17 | 18 | 19 | /** 20 | * 21 | */ 22 | UCLASS() 23 | class PANGAEA_API UEnemyAnimInstance : public UAnimInstance 24 | { 25 | GENERATED_BODY() 26 | 27 | 28 | public: 29 | 30 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Enemy Params") 31 | float Speed; 32 | 33 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Enemy Params") 34 | EEnemyState State; 35 | 36 | UFUNCTION(BlueprintCallable) 37 | void OnStateAnimationEnds(); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /Chapter07/EnemyController.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "EnemyController.h" 5 | #include "Enemy.h" 6 | 7 | void AEnemyController::MakeAttackDecision(APawn* targetPawn) 8 | { 9 | auto controlledCharacter = Cast(GetPawn()); 10 | auto dist = FVector::Dist2D(targetPawn->GetActorLocation(), GetPawn()->GetTargetLocation()); 11 | UE_LOG(LogTemp, Warning, TEXT("Distance=%d"), dist); 12 | if (dist <= controlledCharacter->AttackRange && controlledCharacter->CanAttack()) 13 | { 14 | controlledCharacter->Attack(); 15 | } 16 | } -------------------------------------------------------------------------------- /Chapter07/EnemyController.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AIController.h" 7 | #include "EnemyController.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API AEnemyController : public AAIController 14 | { 15 | GENERATED_BODY() 16 | 17 | 18 | public: 19 | 20 | void MakeAttackDecision(APawn *targetPawn); //AI decision making. Called by PawnTick 21 | }; 22 | -------------------------------------------------------------------------------- /Chapter07/Pangaea.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class Pangaea : ModuleRules 6 | { 7 | public Pangaea(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "NavigationSystem", "AIModule", "Niagara" }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter07/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter07/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter07/PangaeaCharacter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaCharacter.h" 4 | #include "UObject/ConstructorHelpers.h" 5 | #include "Camera/CameraComponent.h" 6 | #include "Components/DecalComponent.h" 7 | #include "Components/CapsuleComponent.h" 8 | #include "GameFramework/CharacterMovementComponent.h" 9 | #include "GameFramework/PlayerController.h" 10 | #include "GameFramework/SpringArmComponent.h" 11 | #include "Materials/Material.h" 12 | #include "Engine/World.h" 13 | 14 | APangaeaCharacter::APangaeaCharacter() 15 | { 16 | // Set size for player capsule 17 | GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); 18 | 19 | // Don't rotate character to camera direction 20 | bUseControllerRotationPitch = false; 21 | bUseControllerRotationYaw = false; 22 | bUseControllerRotationRoll = false; 23 | 24 | // Configure character movement 25 | GetCharacterMovement()->bOrientRotationToMovement = true; // Rotate character to moving direction 26 | GetCharacterMovement()->RotationRate = FRotator(0.f, 640.f, 0.f); 27 | GetCharacterMovement()->bConstrainToPlane = true; 28 | GetCharacterMovement()->bSnapToPlaneAtStart = true; 29 | 30 | // Create a camera boom... 31 | CameraBoom = CreateDefaultSubobject(TEXT("CameraBoom")); 32 | CameraBoom->SetupAttachment(RootComponent); 33 | CameraBoom->SetUsingAbsoluteRotation(true); // Don't want arm to rotate when character does 34 | CameraBoom->TargetArmLength = 800.f; 35 | CameraBoom->SetRelativeRotation(FRotator(-60.f, 0.f, 0.f)); 36 | CameraBoom->bDoCollisionTest = false; // Don't want to pull camera in when it collides with level 37 | 38 | // Create a camera... 39 | TopDownCameraComponent = CreateDefaultSubobject(TEXT("TopDownCamera")); 40 | TopDownCameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); 41 | TopDownCameraComponent->bUsePawnControlRotation = false; // Camera does not rotate relative to arm 42 | 43 | // Activate ticking in order to update the cursor every frame. 44 | PrimaryActorTick.bCanEverTick = true; 45 | PrimaryActorTick.bStartWithTickEnabled = true; 46 | } 47 | 48 | void APangaeaCharacter::Tick(float DeltaSeconds) 49 | { 50 | Super::Tick(DeltaSeconds); 51 | } 52 | -------------------------------------------------------------------------------- /Chapter07/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Character.h" 7 | #include "PangaeaCharacter.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class APangaeaCharacter : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaCharacter(); 16 | 17 | // Called every frame. 18 | virtual void Tick(float DeltaSeconds) override; 19 | 20 | /** Returns TopDownCameraComponent subobject **/ 21 | FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; } 22 | /** Returns CameraBoom subobject **/ 23 | FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; } 24 | 25 | private: 26 | /** Top down camera */ 27 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 28 | class UCameraComponent* TopDownCameraComponent; 29 | 30 | /** Camera boom positioning the camera above the character */ 31 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 32 | class USpringArmComponent* CameraBoom; 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /Chapter07/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameInstance.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter07/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/GameInstance.h" 7 | #include "PangaeaGameInstance.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter07/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaGameMode.h" 4 | #include "PangaeaPlayerController.h" 5 | #include "PangaeaCharacter.h" 6 | #include "UObject/ConstructorHelpers.h" 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_PlayerAvatar")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if(PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter07/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameModeBase.h" 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | }; 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter07/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameState.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter07/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameStateBase.h" 7 | #include "PangaeaGameState.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API APangaeaGameState : public AGameStateBase 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter07/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | /** Input Handlers for Attack action. */ 45 | void OnAttackPressed(); 46 | 47 | private: 48 | bool bInputPressed; // Input is bring pressed 49 | bool bIsTouch; // Is it a touch device 50 | float FollowTime; // For how long it has been pressed 51 | }; 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter07/PlayerAvatarAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PlayerAvatarAnimInstance.h" 5 | #include "PlayerAvatar.h" 6 | 7 | void UPlayerAvatarAnimInstance::OnStateAnimationEnds() 8 | { 9 | if (State == EPlayerState::Attack) 10 | { 11 | State = EPlayerState::Locomotion; 12 | } 13 | else 14 | { 15 | auto playerAvatar = Cast(GetOwningActor()); 16 | 17 | if (State == EPlayerState::Hit) 18 | { 19 | if (playerAvatar->GetHealthPoints() > 0.0f) 20 | { 21 | State = EPlayerState::Locomotion; 22 | } 23 | else 24 | { 25 | State = EPlayerState::Die; 26 | } 27 | 28 | } 29 | else if (State == EPlayerState::Die) 30 | { 31 | playerAvatar->DieProcess(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter07/PlayerAvatarAnimInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Animation/AnimInstance.h" 7 | #include "PlayerAvatarAnimInstance.generated.h" 8 | 9 | UENUM(BlueprintType) 10 | enum class EPlayerState : uint8 11 | { 12 | Locomotion, 13 | Attack, 14 | Hit, 15 | Die 16 | }; 17 | 18 | 19 | /** 20 | * 21 | */ 22 | UCLASS() 23 | class PANGAEA_API UPlayerAvatarAnimInstance : public UAnimInstance 24 | { 25 | GENERATED_BODY() 26 | 27 | 28 | public : 29 | 30 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Avatar Params") 31 | float Speed; 32 | 33 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Avatar Params") 34 | EPlayerState State; 35 | 36 | UFUNCTION(BlueprintCallable) 37 | void OnStateAnimationEnds(); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /Chapter07/Projectile.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "Projectile.h" 5 | 6 | // Sets default values 7 | AProjectile::AProjectile() 8 | { 9 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 10 | PrimaryActorTick.bCanEverTick = true; 11 | 12 | _BoxComponent = CreateDefaultSubobject(TEXT("Box Collision")); 13 | SetRootComponent(_BoxComponent); 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | _MeshComponent->SetupAttachment(_BoxComponent); 17 | } 18 | 19 | // Called when the game starts or when spawned 20 | void AProjectile::BeginPlay() 21 | { 22 | Super::BeginPlay(); 23 | 24 | } 25 | 26 | // Called every frame 27 | void AProjectile::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | } 32 | 33 | -------------------------------------------------------------------------------- /Chapter07/Projectile.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "Components/BoxComponent.h" 8 | #include "Components/StaticMeshComponent.h" 9 | #include "Projectile.generated.h" 10 | 11 | UCLASS(Blueprintable) 12 | class PANGAEA_API AProjectile : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AProjectile(); 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Speed = 100.0f; //the projectile's speed 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Lifespan = 5.0f; //the projectile's lifespan 25 | 26 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 27 | float Damage = 10.0f; //the projectile's damage points 28 | 29 | protected: 30 | // Called when the game starts or when spawned 31 | virtual void BeginPlay() override; 32 | 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 34 | UBoxComponent* _BoxComponent; 35 | 36 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 37 | UStaticMeshComponent* _MeshComponent; 38 | 39 | float _LifeCountingDown; 40 | public: 41 | // Called every frame 42 | virtual void Tick(float DeltaTime) override; 43 | 44 | FORCEINLINE UBoxComponent* GetBoxComponent() const { return _BoxComponent; } 45 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 46 | }; 47 | -------------------------------------------------------------------------------- /Chapter08/Enemy.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Character.h" 7 | #include "Weapon.h" 8 | #include "Enemy.generated.h" 9 | 10 | UCLASS() 11 | class PANGAEA_API AEnemy : public ACharacter 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | // Sets default values for this character's properties 17 | AEnemy(); 18 | 19 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 20 | int HealthPoints = 100; //the character's max health points 21 | 22 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 23 | float Strength = 5; //the character's attack strength 24 | 25 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 26 | float Armer = 1; //the character's defense armer 27 | 28 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 29 | float AttackRange = 200.0f; //the character's attack range 30 | 31 | UPROPERTY(EditAnywhere, Category = "Enemy Params") 32 | float AttackInterval = 3.0f; //the character's attack invertal 33 | 34 | protected: 35 | // Called when the game starts or when spawned 36 | virtual void BeginPlay() override; 37 | 38 | int _HealthPoints; 39 | float _AttackCountingDown; 40 | APawn* _chasedTarget = nullptr; 41 | 42 | UClass* _WeaponClass; 43 | AWeapon* _Weapon; 44 | public: 45 | // Called every frame 46 | virtual void Tick(float DeltaTime) override; 47 | 48 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy", meta = (DisplayName = "Get HP")) 49 | int GetHealthPoints(); //get current health points 50 | 51 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 52 | bool IsKilled(); //check if the character has been killed 53 | 54 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 55 | bool CanAttack(); //check if the character can attack 56 | 57 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 58 | void Chase(APawn* targetPawn); 59 | 60 | void Attack(); 61 | void Hit(int damage); 62 | void DieProcess(); //process when the character is killed 63 | 64 | private: 65 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 66 | class UPawnSensingComponent* PawnSensingComponent; 67 | }; 68 | -------------------------------------------------------------------------------- /Chapter08/EnemyAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "EnemyAnimInstance.h" 5 | #include "Enemy.h" 6 | 7 | void UEnemyAnimInstance::OnStateAnimationEnds() 8 | { 9 | if (State == EEnemyState::Attack) 10 | { 11 | State = EEnemyState::Locomotion; 12 | } 13 | else 14 | { 15 | auto enemy = Cast(GetOwningActor()); 16 | 17 | if (State == EEnemyState::Hit) 18 | { 19 | if (enemy->GetHealthPoints() > 0.0f) 20 | { 21 | State = EEnemyState::Locomotion; 22 | } 23 | else 24 | { 25 | State = EEnemyState::Die; 26 | } 27 | 28 | } 29 | else if (State == EEnemyState::Die) 30 | { 31 | enemy->DieProcess(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter08/EnemyAnimInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Animation/AnimInstance.h" 7 | #include "EnemyAnimInstance.generated.h" 8 | 9 | UENUM(BlueprintType) 10 | enum class EEnemyState : uint8 11 | { 12 | Locomotion, 13 | Attack, 14 | Hit, 15 | Die 16 | }; 17 | 18 | 19 | /** 20 | * 21 | */ 22 | UCLASS() 23 | class PANGAEA_API UEnemyAnimInstance : public UAnimInstance 24 | { 25 | GENERATED_BODY() 26 | 27 | 28 | public: 29 | 30 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Enemy Params") 31 | float Speed; 32 | 33 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Enemy Params") 34 | EEnemyState State; 35 | 36 | UFUNCTION(BlueprintCallable) 37 | void OnStateAnimationEnds(); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /Chapter08/EnemyController.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "EnemyController.h" 5 | #include "Enemy.h" 6 | 7 | void AEnemyController::MakeAttackDecision(APawn* targetPawn) 8 | { 9 | auto controlledCharacter = Cast(GetPawn()); 10 | auto dist = FVector::Dist2D(targetPawn->GetActorLocation(), GetPawn()->GetTargetLocation()); 11 | //UE_LOG(LogTemp, Warning, TEXT("Distance=%d"), dist); 12 | if (dist <= controlledCharacter->AttackRange && controlledCharacter->CanAttack()) 13 | { 14 | controlledCharacter->Attack(); 15 | } 16 | } -------------------------------------------------------------------------------- /Chapter08/EnemyController.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AIController.h" 7 | #include "EnemyController.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API AEnemyController : public AAIController 14 | { 15 | GENERATED_BODY() 16 | 17 | 18 | public: 19 | 20 | void MakeAttackDecision(APawn *targetPawn); //AI decision making. Called by PawnTick 21 | }; 22 | -------------------------------------------------------------------------------- /Chapter08/Pangaea.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class Pangaea : ModuleRules 6 | { 7 | public Pangaea(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "NavigationSystem", "AIModule", "Niagara" }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter08/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter08/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter08/PangaeaCharacter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaCharacter.h" 4 | #include "UObject/ConstructorHelpers.h" 5 | #include "Camera/CameraComponent.h" 6 | #include "Components/DecalComponent.h" 7 | #include "Components/CapsuleComponent.h" 8 | #include "GameFramework/CharacterMovementComponent.h" 9 | #include "GameFramework/PlayerController.h" 10 | #include "GameFramework/SpringArmComponent.h" 11 | #include "Materials/Material.h" 12 | #include "Engine/World.h" 13 | 14 | APangaeaCharacter::APangaeaCharacter() 15 | { 16 | // Set size for player capsule 17 | GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f); 18 | 19 | // Don't rotate character to camera direction 20 | bUseControllerRotationPitch = false; 21 | bUseControllerRotationYaw = false; 22 | bUseControllerRotationRoll = false; 23 | 24 | // Configure character movement 25 | GetCharacterMovement()->bOrientRotationToMovement = true; // Rotate character to moving direction 26 | GetCharacterMovement()->RotationRate = FRotator(0.f, 640.f, 0.f); 27 | GetCharacterMovement()->bConstrainToPlane = true; 28 | GetCharacterMovement()->bSnapToPlaneAtStart = true; 29 | 30 | // Create a camera boom... 31 | CameraBoom = CreateDefaultSubobject(TEXT("CameraBoom")); 32 | CameraBoom->SetupAttachment(RootComponent); 33 | CameraBoom->SetUsingAbsoluteRotation(true); // Don't want arm to rotate when character does 34 | CameraBoom->TargetArmLength = 800.f; 35 | CameraBoom->SetRelativeRotation(FRotator(-60.f, 0.f, 0.f)); 36 | CameraBoom->bDoCollisionTest = false; // Don't want to pull camera in when it collides with level 37 | 38 | // Create a camera... 39 | TopDownCameraComponent = CreateDefaultSubobject(TEXT("TopDownCamera")); 40 | TopDownCameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName); 41 | TopDownCameraComponent->bUsePawnControlRotation = false; // Camera does not rotate relative to arm 42 | 43 | // Activate ticking in order to update the cursor every frame. 44 | PrimaryActorTick.bCanEverTick = true; 45 | PrimaryActorTick.bStartWithTickEnabled = true; 46 | } 47 | 48 | void APangaeaCharacter::Tick(float DeltaSeconds) 49 | { 50 | Super::Tick(DeltaSeconds); 51 | } 52 | -------------------------------------------------------------------------------- /Chapter08/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Character.h" 7 | #include "PangaeaCharacter.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class APangaeaCharacter : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaCharacter(); 16 | 17 | // Called every frame. 18 | virtual void Tick(float DeltaSeconds) override; 19 | 20 | /** Returns TopDownCameraComponent subobject **/ 21 | FORCEINLINE class UCameraComponent* GetTopDownCameraComponent() const { return TopDownCameraComponent; } 22 | /** Returns CameraBoom subobject **/ 23 | FORCEINLINE class USpringArmComponent* GetCameraBoom() const { return CameraBoom; } 24 | 25 | private: 26 | /** Top down camera */ 27 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 28 | class UCameraComponent* TopDownCameraComponent; 29 | 30 | /** Camera boom positioning the camera above the character */ 31 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true")) 32 | class USpringArmComponent* CameraBoom; 33 | }; 34 | 35 | -------------------------------------------------------------------------------- /Chapter08/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameInstance.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter08/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/GameInstance.h" 7 | #include "PangaeaGameInstance.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter08/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaGameMode.h" 4 | #include "PangaeaPlayerController.h" 5 | #include "PangaeaCharacter.h" 6 | #include "UObject/ConstructorHelpers.h" 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_PlayerAvatar")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if(PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | } -------------------------------------------------------------------------------- /Chapter08/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameModeBase.h" 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | }; 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /Chapter08/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameState.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter08/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameStateBase.h" 7 | #include "PangaeaGameState.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API APangaeaGameState : public AGameStateBase 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter08/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | /** Input Handlers for Attack action. */ 45 | void OnAttackPressed(); 46 | 47 | private: 48 | bool bInputPressed; // Input is bring pressed 49 | bool bIsTouch; // Is it a touch device 50 | float FollowTime; // For how long it has been pressed 51 | }; 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter08/PlayerAvatarAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PlayerAvatarAnimInstance.h" 5 | #include "PlayerAvatar.h" 6 | 7 | void UPlayerAvatarAnimInstance::OnStateAnimationEnds() 8 | { 9 | if (State == EPlayerState::Attack) 10 | { 11 | State = EPlayerState::Locomotion; 12 | } 13 | else 14 | { 15 | auto playerAvatar = Cast(GetOwningActor()); 16 | 17 | if (State == EPlayerState::Hit) 18 | { 19 | if (playerAvatar->GetHealthPoints() > 0.0f) 20 | { 21 | State = EPlayerState::Locomotion; 22 | } 23 | else 24 | { 25 | State = EPlayerState::Die; 26 | } 27 | 28 | } 29 | else if (State == EPlayerState::Die) 30 | { 31 | playerAvatar->DieProcess(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Chapter08/PlayerAvatarAnimInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Animation/AnimInstance.h" 7 | #include "PlayerAvatarAnimInstance.generated.h" 8 | 9 | UENUM(BlueprintType) 10 | enum class EPlayerState : uint8 11 | { 12 | Locomotion, 13 | Attack, 14 | Hit, 15 | Die 16 | }; 17 | 18 | 19 | /** 20 | * 21 | */ 22 | UCLASS() 23 | class PANGAEA_API UPlayerAvatarAnimInstance : public UAnimInstance 24 | { 25 | GENERATED_BODY() 26 | 27 | 28 | public : 29 | 30 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Avatar Params") 31 | float Speed; 32 | 33 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Avatar Params") 34 | EPlayerState State; 35 | 36 | UFUNCTION(BlueprintCallable) 37 | void OnStateAnimationEnds(); 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /Chapter08/Projectile.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "Projectile.h" 5 | #include "PlayerAvatar.h" 6 | 7 | // Sets default values 8 | AProjectile::AProjectile() 9 | { 10 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 11 | PrimaryActorTick.bCanEverTick = true; 12 | 13 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 14 | SetRootComponent(_MeshComponent); 15 | } 16 | 17 | // Called when the game starts or when spawned 18 | void AProjectile::BeginPlay() 19 | { 20 | Super::BeginPlay(); 21 | 22 | _LifeCountingDown = Lifespan; 23 | } 24 | 25 | // Called every frame 26 | void AProjectile::Tick(float DeltaTime) 27 | { 28 | Super::Tick(DeltaTime); 29 | 30 | if (_LifeCountingDown > 0.0f) 31 | { 32 | FVector currentLocation = GetActorLocation(); 33 | FVector vel = GetActorRotation().RotateVector(FVector::ForwardVector) * Speed * DeltaTime; 34 | FVector nextLocation = currentLocation + vel; 35 | SetActorLocation(nextLocation); 36 | 37 | //Ray cast check 38 | FHitResult hitResult; 39 | FCollisionObjectQueryParams objCollisionQueryParams; 40 | objCollisionQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); 41 | 42 | if (GetWorld()->LineTraceSingleByObjectType(hitResult, currentLocation, nextLocation, objCollisionQueryParams)) 43 | { 44 | auto playerAvatar = Cast(hitResult.GetActor()); 45 | if (playerAvatar != nullptr) 46 | { 47 | playerAvatar->Hit(Damage); 48 | 49 | PrimaryActorTick.bCanEverTick = false; 50 | Destroy(); 51 | } 52 | } 53 | 54 | //Reduce time 55 | _LifeCountingDown -= DeltaTime; 56 | } 57 | else 58 | { 59 | PrimaryActorTick.bCanEverTick = false; 60 | Destroy(); 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /Chapter08/Projectile.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "Components/BoxComponent.h" 8 | #include "Components/StaticMeshComponent.h" 9 | #include "Projectile.generated.h" 10 | 11 | UCLASS(Blueprintable) 12 | class PANGAEA_API AProjectile : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AProjectile(); 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Speed = 100.0f; //the projectile's speed 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Lifespan = 5.0f; //the projectile's lifespan 25 | 26 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 27 | float Damage = 30.0f; //the projectile's damage points 28 | 29 | protected: 30 | // Called when the game starts or when spawned 31 | virtual void BeginPlay() override; 32 | 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 34 | UStaticMeshComponent* _MeshComponent; 35 | 36 | float _LifeCountingDown; 37 | public: 38 | // Called every frame 39 | virtual void Tick(float DeltaTime) override; 40 | 41 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 42 | }; 43 | -------------------------------------------------------------------------------- /Chapter08/Weapon.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "GameFramework/Character.h" 8 | #include "Components/SphereComponent.h" 9 | #include "Weapon.generated.h" 10 | 11 | UCLASS() 12 | class PANGAEA_API AWeapon : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AWeapon(); 19 | 20 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 21 | ACharacter* Holder = nullptr; 22 | 23 | UPROPERTY(EditAnywhere, Category = "Weapon Params") 24 | float Strength = 10; 25 | 26 | protected: 27 | // Called when the game starts or when spawned 28 | virtual void BeginPlay() override; 29 | 30 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly) 31 | UStaticMeshComponent* _StaticMesh; 32 | 33 | UFUNCTION() 34 | void OnWeaponBeginOverlap(AActor* OverlappedActor, AActor* OtherActor); 35 | 36 | bool IsWithinAttackRange(float AttackRange, AActor* Target); 37 | 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | }; 42 | -------------------------------------------------------------------------------- /Chapter09/ActorPool.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "ActorPool.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter09/ActorPool.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | 8 | 9 | 10 | template 11 | class UActorPool 12 | { 13 | protected: 14 | 15 | TQueue _ActorPool; 16 | public: 17 | UActorPool() 18 | { 19 | 20 | } 21 | ~UActorPool() 22 | { 23 | 24 | } 25 | 26 | void Initialize(int poolSize) 27 | { 28 | 29 | } 30 | 31 | T* GetActor() 32 | { 33 | 34 | } 35 | 36 | void ReturnActor(T* actor) 37 | { 38 | return nullptr; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Chapter09/Enemy.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Enemy.h" 3 | #include "Perception/PawnSensingComponent.h" 4 | #include "GameFramework/CharacterMovementComponent.h" 5 | #include "EnemyController.h" 6 | #include "PangaeaAnimInstance.h" 7 | 8 | AEnemy::AEnemy() 9 | { 10 | PawnSensingComponent = CreateDefaultSubobject(TEXT("PawnSensor")); 11 | 12 | static ConstructorHelpers::FObjectFinder blueprint_finder(TEXT("Blueprint'/Game/TopDown/Blueprints/BP_Hammer.BP_Hammer'")); 13 | _WeaponClass = (UClass*)blueprint_finder.Object->GeneratedClass; 14 | } 15 | 16 | void AEnemy::BeginPlay() 17 | { 18 | Super::BeginPlay(); 19 | 20 | _Weapon = Cast(GetWorld()->SpawnActor(_WeaponClass)); 21 | _Weapon->Holder = this; 22 | _Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("hand_rSocket")); 23 | } 24 | 25 | // Called every frame 26 | void AEnemy::Tick(float DeltaTime) 27 | { 28 | Super::Tick(DeltaTime); 29 | 30 | _AnimInstance->Speed = GetCharacterMovement()->Velocity.Size2D(); 31 | 32 | if (_AttackCountingDown == AttackInterval) 33 | { 34 | _AnimInstance->State = ECharacterState::Attack; 35 | } 36 | 37 | if (_AttackCountingDown > 0.0f) 38 | { 39 | _AttackCountingDown -= DeltaTime; 40 | } 41 | 42 | if (_chasedTarget != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 43 | { 44 | auto enemyController = Cast(GetController()); 45 | enemyController->MakeAttackDecision(_chasedTarget); 46 | } 47 | } 48 | 49 | void AEnemy::Chase(APawn* targetPawn) 50 | { 51 | if (targetPawn != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 52 | { 53 | auto enemyController = Cast(GetController()); 54 | enemyController->MoveToActor(targetPawn, 90.0f); 55 | } 56 | _chasedTarget = targetPawn; 57 | } 58 | 59 | void AEnemy::DieProcess() 60 | { 61 | Super::DieProcess(); 62 | _Weapon->Destroy(); 63 | } 64 | 65 | void AEnemy::Attack() 66 | { 67 | APangaeaCharacter::Attack(); 68 | 69 | GetController()->StopMovement(); 70 | } 71 | 72 | 73 | -------------------------------------------------------------------------------- /Chapter09/Enemy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "PangaeaCharacter.h" 5 | #include "Weapon.h" 6 | 7 | #include "Enemy.generated.h" 8 | 9 | UCLASS() 10 | class PANGAEA_API AEnemy : public APangaeaCharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | AEnemy(); 16 | 17 | protected: 18 | virtual void BeginPlay() override; 19 | 20 | APawn* _chasedTarget = nullptr; 21 | UClass* _WeaponClass; 22 | AWeapon* _Weapon; 23 | 24 | public: 25 | virtual void Tick(float DeltaTime) override; 26 | 27 | void Attack() override; 28 | void DieProcess() override; 29 | 30 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 31 | void Chase(APawn* targetPawn); 32 | private: 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 34 | class UPawnSensingComponent* PawnSensingComponent; 35 | }; 36 | -------------------------------------------------------------------------------- /Chapter09/EnemyController.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "EnemyController.h" 5 | #include "Enemy.h" 6 | 7 | void AEnemyController::MakeAttackDecision(APawn* targetPawn) 8 | { 9 | auto controlledCharacter = Cast(GetPawn()); 10 | auto dist = FVector::Dist2D(targetPawn->GetActorLocation(), GetPawn()->GetTargetLocation()); 11 | //UE_LOG(LogTemp, Warning, TEXT("Distance=%d"), dist); 12 | if (dist <= controlledCharacter->AttackRange && controlledCharacter->CanAttack()) 13 | { 14 | controlledCharacter->Attack(); 15 | } 16 | } -------------------------------------------------------------------------------- /Chapter09/EnemyController.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AIController.h" 7 | #include "EnemyController.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API AEnemyController : public AAIController 14 | { 15 | GENERATED_BODY() 16 | 17 | 18 | public: 19 | 20 | void MakeAttackDecision(APawn *targetPawn); //AI decision making. Called by PawnTick 21 | }; 22 | -------------------------------------------------------------------------------- /Chapter09/Pangaea.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class Pangaea : ModuleRules 6 | { 7 | public Pangaea(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "NavigationSystem", "AIModule", "Niagara" }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter09/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter09/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter09/PangaeaAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaAnimInstance.h" 2 | #include "PangaeaCharacter.h" 3 | 4 | void UPangaeaAnimInstance::OnStateAnimationEnds() 5 | { 6 | if (State == ECharacterState::Attack) 7 | { 8 | State = ECharacterState::Locomotion; 9 | } 10 | else 11 | { 12 | auto character = Cast(GetOwningActor()); 13 | 14 | if (State == ECharacterState::Hit) 15 | { 16 | if (character->GetHealthPoints() > 0.0f) 17 | { 18 | State = ECharacterState::Locomotion; 19 | } 20 | else 21 | { 22 | State = ECharacterState::Die; 23 | } 24 | } 25 | else if (State == ECharacterState::Die) 26 | { 27 | character->DieProcess(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter09/PangaeaAnimInstance.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Animation/AnimInstance.h" 6 | #include "PangaeaAnimInstance.generated.h" 7 | 8 | UENUM(BlueprintType) 9 | enum class ECharacterState : uint8 10 | { 11 | Locomotion, 12 | Attack, 13 | Hit, 14 | Die 15 | }; 16 | 17 | 18 | UCLASS() 19 | class PANGAEA_API UPangaeaAnimInstance : public UAnimInstance 20 | { 21 | GENERATED_BODY() 22 | 23 | public: 24 | 25 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 26 | float Speed; 27 | 28 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 29 | ECharacterState State; 30 | 31 | UFUNCTION(BlueprintCallable) 32 | void OnStateAnimationEnds(); 33 | }; 34 | -------------------------------------------------------------------------------- /Chapter09/PangaeaCharacter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "PangaeaCharacter.h" 4 | #include "PangaeaAnimInstance.h" 5 | #include "UObject/ConstructorHelpers.h" 6 | #include "Camera/CameraComponent.h" 7 | #include "Components/DecalComponent.h" 8 | #include "Components/CapsuleComponent.h" 9 | #include "GameFramework/CharacterMovementComponent.h" 10 | #include "GameFramework/PlayerController.h" 11 | #include "GameFramework/SpringArmComponent.h" 12 | #include "Materials/Material.h" 13 | #include "Engine/World.h" 14 | 15 | APangaeaCharacter::APangaeaCharacter() 16 | { 17 | PrimaryActorTick.bCanEverTick = true; 18 | } 19 | 20 | void APangaeaCharacter::BeginPlay() 21 | { 22 | Super::BeginPlay(); 23 | 24 | _AnimInstance = Cast(GetMesh()->GetAnimInstance()); 25 | _HealthPoints = HealthPoints; 26 | } 27 | 28 | void APangaeaCharacter::Tick(float DeltaSeconds) 29 | { 30 | Super::Tick(DeltaSeconds); 31 | } 32 | 33 | int APangaeaCharacter::GetHealthPoints() 34 | { 35 | return _HealthPoints; 36 | } 37 | 38 | bool APangaeaCharacter::IsKilled() 39 | { 40 | return (_HealthPoints <= 0.0f); 41 | } 42 | 43 | bool APangaeaCharacter::CanAttack() 44 | { 45 | return (_AttackCountingDown <= 0.0f && _AnimInstance->State == ECharacterState::Locomotion); 46 | } 47 | 48 | bool APangaeaCharacter::IsAttacking() 49 | { 50 | return (_AnimInstance->State == ECharacterState::Attack); 51 | } 52 | 53 | void APangaeaCharacter::Attack() 54 | { 55 | _AttackCountingDown = AttackInterval; 56 | } 57 | 58 | void APangaeaCharacter::Hit(int damage) 59 | { 60 | if (IsKilled()) 61 | { 62 | return; 63 | } 64 | 65 | _HealthPoints -= damage; 66 | 67 | 68 | _AnimInstance->State = ECharacterState::Hit; 69 | 70 | if (IsKilled()) 71 | { 72 | PrimaryActorTick.bCanEverTick = false; 73 | } 74 | } 75 | 76 | void APangaeaCharacter::DieProcess() 77 | { 78 | PrimaryActorTick.bCanEverTick = false; 79 | Destroy(); 80 | GEngine->ForceGarbageCollection(true); 81 | } -------------------------------------------------------------------------------- /Chapter09/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "GameFramework/Character.h" 5 | 6 | #include "PangaeaCharacter.generated.h" 7 | 8 | UCLASS(Blueprintable) 9 | class APangaeaCharacter : public ACharacter 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | APangaeaCharacter(); 15 | 16 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 17 | int HealthPoints = 100; //the character's max health points 18 | 19 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 20 | float Strength = 5; //the character's attack strength 21 | 22 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 23 | float Armer = 1; //the character's defense armer 24 | 25 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 26 | float AttackRange = 200.0f; //the character's attack range 27 | 28 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 29 | float AttackInterval = 3.0f; //the character's attack invertval 30 | 31 | public : 32 | virtual void Tick(float DeltaTime) override; 33 | 34 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character", meta = (DisplayName = "Get HP")) 35 | int GetHealthPoints(); //get current health points 36 | 37 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 38 | bool IsKilled(); //check if the character has been killed 39 | 40 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 41 | bool CanAttack(); 42 | bool IsAttacking(); 43 | 44 | virtual void Attack(); 45 | virtual void Hit(int damage); 46 | virtual void DieProcess(); 47 | protected: 48 | virtual void BeginPlay() override; 49 | 50 | class UPangaeaAnimInstance* _AnimInstance; 51 | int _HealthPoints; 52 | float _AttackCountingDown; 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /Chapter09/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameInstance.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter09/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/GameInstance.h" 7 | #include "PangaeaGameInstance.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter09/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaGameMode.h" 2 | 3 | #include "PangaeaCharacter.h" 4 | #include "PangaeaPlayerController.h" 5 | #include "UObject/ConstructorHelpers.h" 6 | 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_PlayerAvatar")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if(PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | } 27 | 28 | APangaeaGameMode::~APangaeaGameMode() 29 | { 30 | AProjectile* fireball; 31 | while (!_FireballPool.IsEmpty() && _FireballPool.Dequeue(fireball)) 32 | { 33 | fireball->Destroy(); 34 | } 35 | _FireballPool.Empty(); 36 | } 37 | 38 | AProjectile* APangaeaGameMode::SpawnOrGetFireball(UClass* projectileClass) 39 | { 40 | AProjectile* fireball = nullptr; 41 | 42 | if (_FireballPool.IsEmpty()) 43 | { 44 | fireball = Cast(GetWorld()->SpawnActor(projectileClass)); 45 | } 46 | else 47 | { 48 | _FireballPool.Dequeue(fireball); 49 | fireball->Reset(); 50 | } 51 | 52 | return fireball; 53 | } 54 | 55 | void APangaeaGameMode::RecycleFireball(AProjectile* projectile) 56 | { 57 | if (projectile == nullptr) 58 | { 59 | return; 60 | } 61 | 62 | projectile->SetActorHiddenInGame(true); 63 | projectile->SetActorEnableCollision(false); 64 | projectile->SetActorTickEnabled(false); 65 | 66 | _FireballPool.Enqueue(projectile); 67 | } -------------------------------------------------------------------------------- /Chapter09/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "GameFramework/GameModeBase.h" 5 | #include "Projectile.h" 6 | 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | ~APangaeaGameMode(); 17 | 18 | AProjectile* SpawnOrGetFireball(UClass * ProjectileClass); 19 | void RecycleFireball(AProjectile* projectile); 20 | 21 | protected: 22 | 23 | TQueue _FireballPool; 24 | }; 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter09/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameState.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter09/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameStateBase.h" 7 | #include "PangaeaGameState.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API APangaeaGameState : public AGameStateBase 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter09/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | /** Input Handlers for Attack action. */ 45 | void OnAttackPressed(); 46 | 47 | private: 48 | bool bInputPressed; // Input is bring pressed 49 | bool bIsTouch; // Is it a touch device 50 | float FollowTime; // For how long it has been pressed 51 | }; 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter09/PlayerAvatar.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "Camera/CameraComponent.h" 6 | #include "GameFramework/SpringArmComponent.h" 7 | #include "PangaeaCharacter.h" 8 | #include "Weapon.h" 9 | 10 | #include "PlayerAvatar.generated.h" 11 | 12 | UCLASS(Blueprintable) 13 | class PANGAEA_API APlayerAvatar : public APangaeaCharacter 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | // Sets default values for this character's properties 19 | APlayerAvatar(); 20 | 21 | 22 | protected: 23 | // Called when the game starts or when spawned 24 | virtual void BeginPlay() override; 25 | 26 | public: 27 | virtual void Tick(float DeltaTime) override; 28 | 29 | // Called to bind functionality to input 30 | virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; 31 | 32 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 33 | void AttachWeapon(AWeapon* Weapon); 34 | 35 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 36 | void DropWeapon(); 37 | 38 | void Attack() override; 39 | 40 | FORCEINLINE class UCameraComponent* GetCameraComponet() const { return _CameraComponent; } 41 | FORCEINLINE class USpringArmComponent* GetSringArmComponet() const { return _SpringArmComponent; } 42 | 43 | private: 44 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 45 | USpringArmComponent* _SpringArmComponent; 46 | 47 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 48 | UCameraComponent* _CameraComponent; 49 | 50 | }; 51 | -------------------------------------------------------------------------------- /Chapter09/Projectile.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "Projectile.h" 5 | 6 | #include "Kismet/GameplayStatics.h" 7 | #include "PangaeaGameMode.h" 8 | #include "PlayerAvatar.h" 9 | 10 | AProjectile::AProjectile() 11 | { 12 | PrimaryActorTick.bCanEverTick = true; 13 | 14 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 15 | SetRootComponent(_MeshComponent); 16 | } 17 | 18 | void AProjectile::BeginPlay() 19 | { 20 | Super::BeginPlay(); 21 | _PangaeaGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld())); 22 | Reset(); 23 | } 24 | 25 | // Called every frame 26 | void AProjectile::Tick(float DeltaTime) 27 | { 28 | Super::Tick(DeltaTime); 29 | 30 | if (_LifeCountingDown > 0.0f) 31 | { 32 | FVector currentLocation = GetActorLocation(); 33 | FVector vel = GetActorRotation().RotateVector(FVector::ForwardVector) * Speed * DeltaTime; 34 | FVector nextLocation = currentLocation + vel; 35 | SetActorLocation(nextLocation); 36 | 37 | //Ray cast check 38 | FHitResult hitResult; 39 | FCollisionObjectQueryParams objCollisionQueryParams; 40 | objCollisionQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); 41 | 42 | if (GetWorld()->LineTraceSingleByObjectType(hitResult, currentLocation, nextLocation, objCollisionQueryParams)) 43 | { 44 | auto playerAvatar = Cast(hitResult.GetActor()); 45 | if (playerAvatar != nullptr) 46 | { 47 | playerAvatar->Hit(Damage); 48 | //Destroy(); 49 | _PangaeaGameMode->RecycleFireball(this); 50 | 51 | } 52 | } 53 | 54 | //Reduce time 55 | _LifeCountingDown -= DeltaTime; 56 | } 57 | else 58 | { 59 | //Destroy() 60 | _PangaeaGameMode->RecycleFireball(this); 61 | } 62 | } 63 | 64 | void AProjectile::Reset() 65 | { 66 | _LifeCountingDown = Lifespan; 67 | SetActorHiddenInGame(false); 68 | SetActorEnableCollision(true); 69 | SetActorTickEnabled(true); 70 | } -------------------------------------------------------------------------------- /Chapter09/Projectile.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "Components/BoxComponent.h" 6 | #include "Components/StaticMeshComponent.h" 7 | #include "GameFramework/Actor.h" 8 | 9 | #include "Projectile.generated.h" 10 | 11 | UCLASS(Blueprintable) 12 | class PANGAEA_API AProjectile : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AProjectile(); 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Speed = 100.0f; //the projectile's speed 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Lifespan = 5.0f; //the projectile's lifespan 25 | 26 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 27 | float Damage = 30.0f; //the projectile's damage points 28 | 29 | protected: 30 | // Called when the game starts or when spawned 31 | virtual void BeginPlay() override; 32 | 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 34 | UStaticMeshComponent* _MeshComponent; 35 | 36 | float _LifeCountingDown; 37 | class APangaeaGameMode* _PangaeaGameMode; 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | 42 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 43 | 44 | void Reset(); 45 | }; 46 | -------------------------------------------------------------------------------- /Chapter09/Weapon.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "GameFramework/Character.h" 8 | #include "Components/SphereComponent.h" 9 | #include "Weapon.generated.h" 10 | 11 | UCLASS() 12 | class PANGAEA_API AWeapon : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AWeapon(); 19 | 20 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 21 | class APangaeaCharacter* Holder = nullptr; 22 | 23 | UPROPERTY(EditAnywhere, Category = "Weapon Params") 24 | float Strength = 10; 25 | 26 | protected: 27 | // Called when the game starts or when spawned 28 | virtual void BeginPlay() override; 29 | 30 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly) 31 | UStaticMeshComponent* _StaticMesh; 32 | 33 | UFUNCTION() 34 | void OnWeaponBeginOverlap(AActor* OverlappedActor, AActor* OtherActor); 35 | 36 | bool IsWithinAttackRange(float AttackRange, AActor* Target); 37 | 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | }; 42 | -------------------------------------------------------------------------------- /Chapter10/ActorPool.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "ActorPool.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter10/ActorPool.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | 8 | 9 | 10 | template 11 | class UActorPool 12 | { 13 | protected: 14 | 15 | TQueue _ActorPool; 16 | public: 17 | UActorPool() 18 | { 19 | 20 | } 21 | ~UActorPool() 22 | { 23 | 24 | } 25 | 26 | void Initialize(int poolSize) 27 | { 28 | 29 | } 30 | 31 | T* GetActor() 32 | { 33 | 34 | } 35 | 36 | void ReturnActor(T* actor) 37 | { 38 | return nullptr; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Chapter10/Enemy.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Enemy.h" 3 | #include "Perception/PawnSensingComponent.h" 4 | #include "GameFramework/CharacterMovementComponent.h" 5 | #include "EnemyController.h" 6 | #include "PangaeaAnimInstance.h" 7 | 8 | AEnemy::AEnemy() 9 | { 10 | PawnSensingComponent = CreateDefaultSubobject(TEXT("PawnSensor")); 11 | 12 | static ConstructorHelpers::FObjectFinder blueprint_finder(TEXT("Blueprint'/Game/TopDown/Blueprints/BP_Hammer.BP_Hammer'")); 13 | _WeaponClass = (UClass*)blueprint_finder.Object->GeneratedClass; 14 | } 15 | 16 | void AEnemy::BeginPlay() 17 | { 18 | Super::BeginPlay(); 19 | 20 | _Weapon = Cast(GetWorld()->SpawnActor(_WeaponClass)); 21 | _Weapon->Holder = this; 22 | _Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("hand_rSocket")); 23 | } 24 | 25 | // Called every frame 26 | void AEnemy::Tick(float DeltaTime) 27 | { 28 | Super::Tick(DeltaTime); 29 | 30 | if (_chasedTarget != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 31 | { 32 | auto enemyController = Cast(GetController()); 33 | enemyController->MakeAttackDecision(_chasedTarget); 34 | } 35 | } 36 | 37 | void AEnemy::Chase(APawn* targetPawn) 38 | { 39 | if (targetPawn != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 40 | { 41 | auto enemyController = Cast(GetController()); 42 | enemyController->MoveToActor(targetPawn, 90.0f); 43 | } 44 | _chasedTarget = targetPawn; 45 | } 46 | 47 | void AEnemy::DieProcess() 48 | { 49 | Super::DieProcess(); 50 | _Weapon->Destroy(); 51 | } 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Chapter10/Enemy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "PangaeaCharacter.h" 5 | #include "Weapon.h" 6 | 7 | #include "Enemy.generated.h" 8 | 9 | UCLASS() 10 | class PANGAEA_API AEnemy : public APangaeaCharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | AEnemy(); 16 | 17 | protected: 18 | virtual void BeginPlay() override; 19 | 20 | APawn* _chasedTarget = nullptr; 21 | UClass* _WeaponClass; 22 | AWeapon* _Weapon; 23 | 24 | public: 25 | virtual void Tick(float DeltaTime) override; 26 | 27 | void DieProcess() override; 28 | 29 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 30 | void Chase(APawn* targetPawn); 31 | private: 32 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 33 | class UPawnSensingComponent* PawnSensingComponent; 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter10/EnemyController.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "EnemyController.h" 5 | #include "Enemy.h" 6 | 7 | void AEnemyController::MakeAttackDecision(APawn* targetPawn) 8 | { 9 | auto enemy = Cast(GetPawn()); 10 | auto dist = FVector::Dist2D(targetPawn->GetActorLocation(), GetPawn()->GetTargetLocation()); 11 | 12 | if (dist <= enemy->AttackRange && enemy->CanAttack()) 13 | { 14 | StopMovement(); 15 | enemy->Attack_Broadcast_RPC(); 16 | } 17 | } -------------------------------------------------------------------------------- /Chapter10/EnemyController.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AIController.h" 7 | #include "EnemyController.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API AEnemyController : public AAIController 14 | { 15 | GENERATED_BODY() 16 | 17 | 18 | public: 19 | 20 | void MakeAttackDecision(APawn *targetPawn); //AI decision making. Called by PawnTick 21 | }; 22 | -------------------------------------------------------------------------------- /Chapter10/HealthBarWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "HealthBarWidget.h" 2 | 3 | -------------------------------------------------------------------------------- /Chapter10/HealthBarWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Components/ProgressBar.h" 5 | #include "Blueprint/UserWidget.h" 6 | #include "HealthBarWidget.generated.h" 7 | 8 | UCLASS() 9 | class PANGAEA_API UHealthBarWidget : public UUserWidget 10 | { 11 | GENERATED_BODY() 12 | 13 | 14 | public: 15 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (BindWidget)) 16 | UProgressBar* HealthProgressBar; 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter10/Pangaea.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class Pangaea : ModuleRules 6 | { 7 | public Pangaea(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "NavigationSystem", "AIModule", "Niagara" }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter10/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter10/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter10/PangaeaAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaAnimInstance.h" 2 | #include "PangaeaCharacter.h" 3 | 4 | void UPangaeaAnimInstance::OnStateAnimationEnds() 5 | { 6 | if (State == ECharacterState::Attack) 7 | { 8 | State = ECharacterState::Locomotion; 9 | } 10 | else 11 | { 12 | auto character = Cast(GetOwningActor()); 13 | 14 | if (State == ECharacterState::Hit) 15 | { 16 | if (character->GetHealthPoints() > 0.0f) 17 | { 18 | State = ECharacterState::Locomotion; 19 | } 20 | else 21 | { 22 | State = ECharacterState::Die; 23 | } 24 | } 25 | else if (State == ECharacterState::Die) 26 | { 27 | character->DieProcess(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter10/PangaeaAnimInstance.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Animation/AnimInstance.h" 6 | #include "PangaeaAnimInstance.generated.h" 7 | 8 | UENUM(BlueprintType) 9 | enum class ECharacterState : uint8 10 | { 11 | Locomotion, 12 | Attack, 13 | Hit, 14 | Die 15 | }; 16 | 17 | 18 | UCLASS() 19 | class PANGAEA_API UPangaeaAnimInstance : public UAnimInstance 20 | { 21 | GENERATED_BODY() 22 | 23 | public: 24 | 25 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 26 | float Speed; 27 | 28 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 29 | ECharacterState State; 30 | 31 | UFUNCTION(BlueprintCallable) 32 | void OnStateAnimationEnds(); 33 | }; 34 | -------------------------------------------------------------------------------- /Chapter10/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "HealthBarWidget.h" 5 | #include "GameFramework/Character.h" 6 | 7 | #include "PangaeaCharacter.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class APangaeaCharacter : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaCharacter(); 16 | 17 | void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; 18 | 19 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 20 | int HealthPoints = 100; //the character's max health points 21 | 22 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 23 | float Strength = 5; //the character's attack strength 24 | 25 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 26 | float Armer = 1; //the character's defense armer 27 | 28 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 29 | float AttackRange = 200.0f; //the character's attack range 30 | 31 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 32 | float AttackInterval = 3.0f; //the character's attack invertval 33 | 34 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 35 | UUserWidget* HealthBarWidget; 36 | 37 | public : 38 | virtual void Tick(float DeltaTime) override; 39 | 40 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character", meta = (DisplayName = "Get HP")) 41 | int GetHealthPoints(); //get current health points 42 | 43 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 44 | bool IsKilled(); //check if the character has been killed 45 | 46 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 47 | bool CanAttack(); 48 | bool IsAttacking(); 49 | 50 | virtual void Attack(); 51 | virtual void Hit(int damage); 52 | virtual void DieProcess(); 53 | 54 | public: 55 | 56 | UFUNCTION(NetMultiCast, Reliable) 57 | void Attack_Broadcast_RPC(); 58 | 59 | protected: 60 | virtual void BeginPlay() override; 61 | 62 | class UPangaeaAnimInstance* _AnimInstance; 63 | 64 | float _AttackCountingDown; 65 | 66 | UPROPERTY(Replicatedusing = OnHealthPointsChanged) 67 | int _HealthPoints; 68 | 69 | UFUNCTION() 70 | void OnHealthPointsChanged(); 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /Chapter10/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameInstance.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter10/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/GameInstance.h" 7 | #include "PangaeaGameInstance.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter10/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaGameMode.h" 2 | 3 | #include "PangaeaCharacter.h" 4 | #include "PangaeaPlayerController.h" 5 | #include "UObject/ConstructorHelpers.h" 6 | 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_PlayerAvatar")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if(PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | } 27 | 28 | APangaeaGameMode::~APangaeaGameMode() 29 | { 30 | AProjectile* fireball; 31 | while (!_FireballPool.IsEmpty() && _FireballPool.Dequeue(fireball)) 32 | { 33 | fireball->Destroy(); 34 | } 35 | _FireballPool.Empty(); 36 | } 37 | 38 | AProjectile* APangaeaGameMode::SpawnOrGetFireball(UClass* projectileClass) 39 | { 40 | AProjectile* fireball = nullptr; 41 | 42 | if (_FireballPool.IsEmpty()) 43 | { 44 | fireball = Cast(GetWorld()->SpawnActor(projectileClass)); 45 | } 46 | else 47 | { 48 | _FireballPool.Dequeue(fireball); 49 | fireball->Reset(); 50 | } 51 | 52 | return fireball; 53 | } 54 | 55 | void APangaeaGameMode::RecycleFireball(AProjectile* projectile) 56 | { 57 | if (projectile == nullptr) 58 | { 59 | return; 60 | } 61 | 62 | projectile->SetActorHiddenInGame(true); 63 | projectile->SetActorEnableCollision(false); 64 | projectile->SetActorTickEnabled(false); 65 | 66 | _FireballPool.Enqueue(projectile); 67 | } -------------------------------------------------------------------------------- /Chapter10/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "GameFramework/GameModeBase.h" 5 | #include "Projectile.h" 6 | 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | ~APangaeaGameMode(); 17 | 18 | AProjectile* SpawnOrGetFireball(UClass * ProjectileClass); 19 | void RecycleFireball(AProjectile* projectile); 20 | 21 | protected: 22 | 23 | TQueue _FireballPool; 24 | }; 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter10/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "PangaeaGameState.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter10/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/GameStateBase.h" 7 | #include "PangaeaGameState.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API APangaeaGameState : public AGameStateBase 14 | { 15 | GENERATED_BODY() 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter10/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | /** Input Handlers for Attack action. */ 45 | void OnAttackPressed(); 46 | 47 | private: 48 | bool bInputPressed; // Input is bring pressed 49 | bool bIsTouch; // Is it a touch device 50 | float FollowTime; // For how long it has been pressed 51 | }; 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter10/PlayerAvatar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Camera/CameraComponent.h" 4 | #include "GameFramework/SpringArmComponent.h" 5 | #include "PangaeaCharacter.h" 6 | #include "Weapon.h" 7 | 8 | #include "PlayerAvatar.generated.h" 9 | 10 | UCLASS(Blueprintable) 11 | class PANGAEA_API APlayerAvatar : public APangaeaCharacter 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | APlayerAvatar(); 17 | 18 | 19 | protected: 20 | virtual void BeginPlay() override; 21 | 22 | public: 23 | virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; 24 | 25 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 26 | void AttachWeapon(AWeapon* Weapon); 27 | 28 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 29 | void DropWeapon(); 30 | 31 | FORCEINLINE class UCameraComponent* GetCameraComponet() const { return _CameraComponent; } 32 | FORCEINLINE class USpringArmComponent* GetSringArmComponet() const { return _SpringArmComponent; } 33 | 34 | UFUNCTION(Server, Reliable) 35 | void Attack_RPC(); 36 | 37 | private: 38 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 39 | USpringArmComponent* _SpringArmComponent; 40 | 41 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 42 | UCameraComponent* _CameraComponent; 43 | 44 | }; 45 | -------------------------------------------------------------------------------- /Chapter10/Projectile.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "Projectile.h" 5 | 6 | #include "Kismet/GameplayStatics.h" 7 | #include "PangaeaGameMode.h" 8 | #include "PlayerAvatar.h" 9 | 10 | AProjectile::AProjectile() 11 | { 12 | PrimaryActorTick.bCanEverTick = true; 13 | bReplicates = true; 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | SetRootComponent(_MeshComponent); 17 | } 18 | 19 | void AProjectile::BeginPlay() 20 | { 21 | Super::BeginPlay(); 22 | _PangaeaGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld())); 23 | Reset(); 24 | } 25 | 26 | // Called every frame 27 | void AProjectile::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | if (GetNetMode() == NM_Client) 32 | { 33 | return; 34 | } 35 | 36 | if (_LifeCountingDown > 0.0f) 37 | { 38 | FVector currentLocation = GetActorLocation(); 39 | FVector vel = GetActorRotation().RotateVector(FVector::ForwardVector) * Speed * DeltaTime; 40 | FVector nextLocation = currentLocation + vel; 41 | SetActorLocation(nextLocation); 42 | 43 | //Ray cast check 44 | FHitResult hitResult; 45 | FCollisionObjectQueryParams objCollisionQueryParams; 46 | objCollisionQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); 47 | 48 | if (GetWorld()->LineTraceSingleByObjectType(hitResult, currentLocation, nextLocation, objCollisionQueryParams)) 49 | { 50 | auto playerAvatar = Cast(hitResult.GetActor()); 51 | if (playerAvatar != nullptr) 52 | { 53 | playerAvatar->Hit(Damage); 54 | //Destroy(); 55 | _PangaeaGameMode->RecycleFireball(this); 56 | 57 | } 58 | } 59 | 60 | //Reduce time 61 | _LifeCountingDown -= DeltaTime; 62 | } 63 | else 64 | { 65 | //Destroy() 66 | _PangaeaGameMode->RecycleFireball(this); 67 | } 68 | } 69 | 70 | void AProjectile::Reset() 71 | { 72 | _LifeCountingDown = Lifespan; 73 | SetActorHiddenInGame(false); 74 | SetActorEnableCollision(true); 75 | SetActorTickEnabled(true); 76 | } -------------------------------------------------------------------------------- /Chapter10/Projectile.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "Components/BoxComponent.h" 6 | #include "Components/StaticMeshComponent.h" 7 | #include "GameFramework/Actor.h" 8 | 9 | #include "Projectile.generated.h" 10 | 11 | UCLASS(Blueprintable) 12 | class PANGAEA_API AProjectile : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AProjectile(); 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Speed = 100.0f; //the projectile's speed 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Lifespan = 5.0f; //the projectile's lifespan 25 | 26 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 27 | float Damage = 30.0f; //the projectile's damage points 28 | 29 | protected: 30 | // Called when the game starts or when spawned 31 | virtual void BeginPlay() override; 32 | 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 34 | UStaticMeshComponent* _MeshComponent; 35 | 36 | float _LifeCountingDown; 37 | class APangaeaGameMode* _PangaeaGameMode; 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | 42 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 43 | 44 | void Reset(); 45 | }; 46 | -------------------------------------------------------------------------------- /Chapter10/Weapon.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "GameFramework/Character.h" 8 | #include "Components/SphereComponent.h" 9 | #include "Weapon.generated.h" 10 | 11 | UCLASS() 12 | class PANGAEA_API AWeapon : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AWeapon(); 19 | 20 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 21 | class APangaeaCharacter* Holder = nullptr; 22 | 23 | UPROPERTY(EditAnywhere, Category = "Weapon Params") 24 | float Strength = 10; 25 | 26 | protected: 27 | // Called when the game starts or when spawned 28 | virtual void BeginPlay() override; 29 | 30 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly) 31 | UStaticMeshComponent* _StaticMesh; 32 | 33 | UFUNCTION() 34 | void OnWeaponBeginOverlap(AActor* OverlappedActor, AActor* OtherActor); 35 | 36 | bool IsWithinAttackRange(float AttackRange, AActor* Target); 37 | 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | }; 42 | -------------------------------------------------------------------------------- /Chapter11/ActorPool.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "ActorPool.h" 5 | 6 | -------------------------------------------------------------------------------- /Chapter11/ActorPool.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | 8 | 9 | 10 | template 11 | class UActorPool 12 | { 13 | protected: 14 | 15 | TQueue _ActorPool; 16 | public: 17 | UActorPool() 18 | { 19 | 20 | } 21 | ~UActorPool() 22 | { 23 | 24 | } 25 | 26 | void Initialize(int poolSize) 27 | { 28 | 29 | } 30 | 31 | T* GetActor() 32 | { 33 | 34 | } 35 | 36 | void ReturnActor(T* actor) 37 | { 38 | return nullptr; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Chapter11/Enemy.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Enemy.h" 3 | #include "Perception/PawnSensingComponent.h" 4 | #include "GameFramework/CharacterMovementComponent.h" 5 | #include "EnemyController.h" 6 | #include "PangaeaAnimInstance.h" 7 | 8 | AEnemy::AEnemy() 9 | { 10 | PawnSensingComponent = CreateDefaultSubobject(TEXT("PawnSensor")); 11 | 12 | static ConstructorHelpers::FObjectFinder blueprint_finder(TEXT("Blueprint'/Game/TopDown/Blueprints/BP_Hammer.BP_Hammer'")); 13 | _WeaponClass = (UClass*)blueprint_finder.Object->GeneratedClass; 14 | } 15 | 16 | void AEnemy::BeginPlay() 17 | { 18 | Super::BeginPlay(); 19 | 20 | _Weapon = Cast(GetWorld()->SpawnActor(_WeaponClass)); 21 | _Weapon->Holder = this; 22 | _Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("hand_rSocket")); 23 | } 24 | 25 | // Called every frame 26 | void AEnemy::Tick(float DeltaTime) 27 | { 28 | Super::Tick(DeltaTime); 29 | 30 | if (_chasedTarget != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 31 | { 32 | auto enemyController = Cast(GetController()); 33 | enemyController->MakeAttackDecision(_chasedTarget); 34 | } 35 | } 36 | 37 | void AEnemy::Chase(APawn* targetPawn) 38 | { 39 | if (targetPawn != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 40 | { 41 | auto enemyController = Cast(GetController()); 42 | enemyController->MoveToActor(targetPawn, 90.0f); 43 | } 44 | _chasedTarget = targetPawn; 45 | } 46 | 47 | void AEnemy::DieProcess() 48 | { 49 | Super::DieProcess(); 50 | _Weapon->Destroy(); 51 | } 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Chapter11/Enemy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "PangaeaCharacter.h" 5 | #include "Weapon.h" 6 | 7 | #include "Enemy.generated.h" 8 | 9 | UCLASS() 10 | class PANGAEA_API AEnemy : public APangaeaCharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | AEnemy(); 16 | 17 | protected: 18 | virtual void BeginPlay() override; 19 | 20 | APawn* _chasedTarget = nullptr; 21 | UClass* _WeaponClass; 22 | AWeapon* _Weapon; 23 | 24 | public: 25 | virtual void Tick(float DeltaTime) override; 26 | 27 | void DieProcess() override; 28 | 29 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 30 | void Chase(APawn* targetPawn); 31 | private: 32 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 33 | class UPawnSensingComponent* PawnSensingComponent; 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter11/EnemyController.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "EnemyController.h" 5 | #include "Enemy.h" 6 | 7 | void AEnemyController::MakeAttackDecision(APawn* targetPawn) 8 | { 9 | auto enemy = Cast(GetPawn()); 10 | auto dist = FVector::Dist2D(targetPawn->GetActorLocation(), GetPawn()->GetTargetLocation()); 11 | 12 | if (dist <= enemy->AttackRange && enemy->CanAttack()) 13 | { 14 | StopMovement(); 15 | enemy->Attack_Broadcast_RPC(); 16 | } 17 | } -------------------------------------------------------------------------------- /Chapter11/EnemyController.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AIController.h" 7 | #include "EnemyController.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class PANGAEA_API AEnemyController : public AAIController 14 | { 15 | GENERATED_BODY() 16 | 17 | 18 | public: 19 | 20 | void MakeAttackDecision(APawn *targetPawn); //AI decision making. Called by PawnTick 21 | }; 22 | -------------------------------------------------------------------------------- /Chapter11/HealthBarWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "HealthBarWidget.h" 2 | 3 | -------------------------------------------------------------------------------- /Chapter11/HealthBarWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Components/ProgressBar.h" 5 | #include "Blueprint/UserWidget.h" 6 | #include "HealthBarWidget.generated.h" 7 | 8 | UCLASS() 9 | class PANGAEA_API UHealthBarWidget : public UUserWidget 10 | { 11 | GENERATED_BODY() 12 | 13 | 14 | public: 15 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (BindWidget)) 16 | UProgressBar* HealthProgressBar; 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter11/Pangaea.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | 5 | public class Pangaea : ModuleRules 6 | { 7 | public Pangaea(ReadOnlyTargetRules Target) : base(Target) 8 | { 9 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 10 | 11 | PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "NavigationSystem", "AIModule", "Niagara" }); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Chapter11/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter11/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter11/PangaeaAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaAnimInstance.h" 2 | #include "PangaeaCharacter.h" 3 | 4 | void UPangaeaAnimInstance::OnStateAnimationEnds() 5 | { 6 | if (State == ECharacterState::Attack) 7 | { 8 | State = ECharacterState::Locomotion; 9 | } 10 | else 11 | { 12 | auto character = Cast(GetOwningActor()); 13 | 14 | if (State == ECharacterState::Hit) 15 | { 16 | if (character->GetHealthPoints() > 0.0f) 17 | { 18 | State = ECharacterState::Locomotion; 19 | } 20 | else 21 | { 22 | State = ECharacterState::Die; 23 | } 24 | } 25 | else if (State == ECharacterState::Die) 26 | { 27 | character->DieProcess(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter11/PangaeaAnimInstance.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Animation/AnimInstance.h" 6 | #include "PangaeaAnimInstance.generated.h" 7 | 8 | UENUM(BlueprintType) 9 | enum class ECharacterState : uint8 10 | { 11 | Locomotion, 12 | Attack, 13 | Hit, 14 | Die 15 | }; 16 | 17 | 18 | UCLASS() 19 | class PANGAEA_API UPangaeaAnimInstance : public UAnimInstance 20 | { 21 | GENERATED_BODY() 22 | 23 | public: 24 | 25 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 26 | float Speed; 27 | 28 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 29 | ECharacterState State; 30 | 31 | UFUNCTION(BlueprintCallable) 32 | void OnStateAnimationEnds(); 33 | 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter11/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "HealthBarWidget.h" 5 | #include "GameFramework/Character.h" 6 | 7 | #include "PangaeaCharacter.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class APangaeaCharacter : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaCharacter(); 16 | 17 | void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; 18 | 19 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 20 | int HealthPoints = 100; //the character's max health points 21 | 22 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 23 | float Strength = 5; //the character's attack strength 24 | 25 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 26 | float Armer = 1; //the character's defense armer 27 | 28 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 29 | float AttackRange = 200.0f; //the character's attack range 30 | 31 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 32 | float AttackInterval = 3.0f; //the character's attack invertval 33 | 34 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 35 | UUserWidget* HealthBarWidget; 36 | 37 | public : 38 | virtual void Tick(float DeltaTime) override; 39 | 40 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character", meta = (DisplayName = "Get HP")) 41 | int GetHealthPoints(); //get current health points 42 | 43 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 44 | bool IsKilled(); //check if the character has been killed 45 | 46 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 47 | bool CanAttack(); 48 | bool IsAttacking(); 49 | 50 | virtual void Attack(); 51 | virtual void Hit(int damage); 52 | virtual void DieProcess(); 53 | 54 | public: 55 | 56 | UFUNCTION(NetMultiCast, Reliable) 57 | void Attack_Broadcast_RPC(); 58 | 59 | protected: 60 | virtual void BeginPlay() override; 61 | 62 | class UPangaeaAnimInstance* _AnimInstance; 63 | 64 | float _AttackCountingDown; 65 | 66 | UPROPERTY(Replicatedusing = OnHealthPointsChanged) 67 | int _HealthPoints; 68 | 69 | UFUNCTION() 70 | void OnHealthPointsChanged(); 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /Chapter11/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "PangaeaGameInstance.h" 3 | #include "Kismet/GameplayStatics.h" 4 | 5 | void UPangaeaGameInstance::StartListenServer() 6 | { 7 | auto world = GEngine->GetCurrentPlayWorld(); 8 | UGameplayStatics::OpenLevel(world, "TopDownMap", true, "?listen"); 9 | } 10 | 11 | void UPangaeaGameInstance::JoinAsClient(FString IPAddress) 12 | { 13 | auto world = GEngine->GetCurrentPlayWorld(); 14 | UGameplayStatics::OpenLevel(world, *IPAddress, true, "?join"); 15 | } 16 | 17 | 18 | void UPangaeaGameInstance::LeaveGame() 19 | { 20 | auto world = GEngine->GetCurrentPlayWorld(); 21 | UGameplayStatics::OpenLevel(world, "LobbyMap"); 22 | } -------------------------------------------------------------------------------- /Chapter11/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Engine/GameInstance.h" 5 | #include "PangaeaGameInstance.generated.h" 6 | 7 | 8 | UCLASS() 9 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | 15 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 16 | void StartListenServer(); 17 | 18 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 19 | void JoinAsClient(FString IPAddress); 20 | 21 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 22 | void LeaveGame(); 23 | 24 | }; 25 | -------------------------------------------------------------------------------- /Chapter11/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaGameMode.h" 2 | #include "PangaeaCharacter.h" 3 | #include "PangaeaPlayerController.h" 4 | #include "PangaeaGameState.h" 5 | #include "UObject/ConstructorHelpers.h" 6 | 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_PlayerAvatar")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if(PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | 27 | GameStateClass = APangaeaGameState::StaticClass(); 28 | } 29 | 30 | APangaeaGameMode::~APangaeaGameMode() 31 | { 32 | AProjectile* fireball; 33 | while (!_FireballPool.IsEmpty() && _FireballPool.Dequeue(fireball)) 34 | { 35 | fireball->Destroy(); 36 | } 37 | _FireballPool.Empty(); 38 | } 39 | 40 | AProjectile* APangaeaGameMode::SpawnOrGetFireball(UClass* projectileClass) 41 | { 42 | AProjectile* fireball = nullptr; 43 | 44 | if (_FireballPool.IsEmpty()) 45 | { 46 | fireball = Cast(GetWorld()->SpawnActor(projectileClass)); 47 | } 48 | else 49 | { 50 | _FireballPool.Dequeue(fireball); 51 | fireball->Reset(); 52 | } 53 | 54 | return fireball; 55 | } 56 | 57 | void APangaeaGameMode::RecycleFireball(AProjectile* projectile) 58 | { 59 | if (projectile == nullptr) 60 | { 61 | return; 62 | } 63 | 64 | projectile->SetActorHiddenInGame(true); 65 | projectile->SetActorEnableCollision(false); 66 | projectile->SetActorTickEnabled(false); 67 | 68 | _FireballPool.Enqueue(projectile); 69 | } -------------------------------------------------------------------------------- /Chapter11/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "GameFramework/GameModeBase.h" 5 | #include "Projectile.h" 6 | 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | ~APangaeaGameMode(); 17 | 18 | AProjectile* SpawnOrGetFireball(UClass * ProjectileClass); 19 | void RecycleFireball(AProjectile* projectile); 20 | 21 | protected: 22 | 23 | TQueue _FireballPool; 24 | }; 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter11/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaGameState.h" 2 | #include 3 | 4 | void APangaeaGameState::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const 5 | { 6 | Super::GetLifetimeReplicatedProps(OutLifetimeProps); 7 | DOREPLIFETIME(APangaeaGameState, Timer); 8 | } 9 | 10 | void APangaeaGameState::OnTimerChanged() 11 | { 12 | OnTimerChangedDelegate.Broadcast(Timer); 13 | } 14 | 15 | void APangaeaGameState::OnGameWin() 16 | { 17 | GameWin = true; 18 | OnGameWinLoseDelegate.Broadcast(true); 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter11/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "GameFramework/GameStateBase.h" 5 | #include "PangaeaGameState.generated.h" 6 | 7 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTimerChangedDelegate, float, Timer); 8 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGameWinLoseDelegate, bool, Win); 9 | 10 | UCLASS() 11 | class PANGAEA_API APangaeaGameState : public AGameStateBase 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | 17 | void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; 18 | 19 | public: 20 | 21 | UPROPERTY(BlueprintAssignable, Category = "Pangaea") 22 | FOnTimerChangedDelegate OnTimerChangedDelegate; 23 | 24 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 25 | void OnTimerChanged(); 26 | 27 | UPROPERTY(BlueprintReadWrite, ReplicatedUsing = OnTimerChanged, Category = "Pangaea") 28 | float Timer = 0; 29 | 30 | UPROPERTY(BlueprintAssignable, Category = "Pangaea") 31 | FOnGameWinLoseDelegate OnGameWinLoseDelegate; 32 | 33 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 34 | void OnGameWin(); 35 | 36 | 37 | UPROPERTY(BlueprintReadWrite, ReplicatedUsing = OnGameWin, Category = "Pangaea") 38 | bool GameWin; 39 | 40 | }; 41 | -------------------------------------------------------------------------------- /Chapter11/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | /** Input Handlers for Attack action. */ 45 | void OnAttackPressed(); 46 | 47 | private: 48 | bool bInputPressed; // Input is bring pressed 49 | bool bIsTouch; // Is it a touch device 50 | float FollowTime; // For how long it has been pressed 51 | }; 52 | 53 | 54 | -------------------------------------------------------------------------------- /Chapter11/PlayerAvatar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Camera/CameraComponent.h" 4 | #include "GameFramework/SpringArmComponent.h" 5 | #include "PangaeaCharacter.h" 6 | #include "Weapon.h" 7 | 8 | #include "PlayerAvatar.generated.h" 9 | 10 | UCLASS(Blueprintable) 11 | class PANGAEA_API APlayerAvatar : public APangaeaCharacter 12 | { 13 | GENERATED_BODY() 14 | 15 | public: 16 | APlayerAvatar(); 17 | 18 | 19 | protected: 20 | virtual void BeginPlay() override; 21 | 22 | public: 23 | virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; 24 | 25 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 26 | void AttachWeapon(AWeapon* Weapon); 27 | 28 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 29 | void DropWeapon(); 30 | 31 | FORCEINLINE class UCameraComponent* GetCameraComponet() const { return _CameraComponent; } 32 | FORCEINLINE class USpringArmComponent* GetSringArmComponet() const { return _SpringArmComponent; } 33 | 34 | UFUNCTION(Server, Reliable) 35 | void Attack_RPC(); 36 | 37 | private: 38 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 39 | USpringArmComponent* _SpringArmComponent; 40 | 41 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 42 | UCameraComponent* _CameraComponent; 43 | 44 | }; 45 | -------------------------------------------------------------------------------- /Chapter11/Projectile.cpp: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | 4 | #include "Projectile.h" 5 | 6 | #include "Kismet/GameplayStatics.h" 7 | #include "PangaeaGameMode.h" 8 | #include "PlayerAvatar.h" 9 | 10 | AProjectile::AProjectile() 11 | { 12 | PrimaryActorTick.bCanEverTick = true; 13 | bReplicates = true; 14 | 15 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 16 | SetRootComponent(_MeshComponent); 17 | } 18 | 19 | void AProjectile::BeginPlay() 20 | { 21 | Super::BeginPlay(); 22 | _PangaeaGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld())); 23 | Reset(); 24 | } 25 | 26 | // Called every frame 27 | void AProjectile::Tick(float DeltaTime) 28 | { 29 | Super::Tick(DeltaTime); 30 | 31 | if (GetNetMode() == NM_Client) 32 | { 33 | return; 34 | } 35 | 36 | if (_LifeCountingDown > 0.0f) 37 | { 38 | FVector currentLocation = GetActorLocation(); 39 | FVector vel = GetActorRotation().RotateVector(FVector::ForwardVector) * Speed * DeltaTime; 40 | FVector nextLocation = currentLocation + vel; 41 | SetActorLocation(nextLocation); 42 | 43 | //Ray cast check 44 | FHitResult hitResult; 45 | FCollisionObjectQueryParams objCollisionQueryParams; 46 | objCollisionQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); 47 | 48 | if (GetWorld()->LineTraceSingleByObjectType(hitResult, currentLocation, nextLocation, objCollisionQueryParams)) 49 | { 50 | auto playerAvatar = Cast(hitResult.GetActor()); 51 | if (playerAvatar != nullptr) 52 | { 53 | playerAvatar->Hit(Damage); 54 | //Destroy(); 55 | _PangaeaGameMode->RecycleFireball(this); 56 | 57 | } 58 | } 59 | 60 | //Reduce time 61 | _LifeCountingDown -= DeltaTime; 62 | } 63 | else 64 | { 65 | //Destroy() 66 | _PangaeaGameMode->RecycleFireball(this); 67 | } 68 | } 69 | 70 | void AProjectile::Reset() 71 | { 72 | _LifeCountingDown = Lifespan; 73 | SetActorHiddenInGame(false); 74 | SetActorEnableCollision(true); 75 | SetActorTickEnabled(true); 76 | } -------------------------------------------------------------------------------- /Chapter11/Projectile.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "Components/BoxComponent.h" 6 | #include "Components/StaticMeshComponent.h" 7 | #include "GameFramework/Actor.h" 8 | 9 | #include "Projectile.generated.h" 10 | 11 | UCLASS(Blueprintable) 12 | class PANGAEA_API AProjectile : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AProjectile(); 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Speed = 100.0f; //the projectile's speed 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Lifespan = 5.0f; //the projectile's lifespan 25 | 26 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 27 | float Damage = 30.0f; //the projectile's damage points 28 | 29 | protected: 30 | // Called when the game starts or when spawned 31 | virtual void BeginPlay() override; 32 | 33 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 34 | UStaticMeshComponent* _MeshComponent; 35 | 36 | float _LifeCountingDown; 37 | class APangaeaGameMode* _PangaeaGameMode; 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | 42 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 43 | 44 | void Reset(); 45 | }; 46 | -------------------------------------------------------------------------------- /Chapter11/Weapon.h: -------------------------------------------------------------------------------- 1 | // Fill out your copyright notice in the Description page of Project Settings. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "GameFramework/Actor.h" 7 | #include "GameFramework/Character.h" 8 | #include "Components/SphereComponent.h" 9 | #include "Weapon.generated.h" 10 | 11 | UCLASS() 12 | class PANGAEA_API AWeapon : public AActor 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | // Sets default values for this actor's properties 18 | AWeapon(); 19 | 20 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 21 | class APangaeaCharacter* Holder = nullptr; 22 | 23 | UPROPERTY(EditAnywhere, Category = "Weapon Params") 24 | float Strength = 10; 25 | 26 | protected: 27 | // Called when the game starts or when spawned 28 | virtual void BeginPlay() override; 29 | 30 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly) 31 | UStaticMeshComponent* _StaticMesh; 32 | 33 | UFUNCTION() 34 | void OnWeaponBeginOverlap(AActor* OverlappedActor, AActor* OtherActor); 35 | 36 | bool IsWithinAttackRange(float AttackRange, AActor* Target); 37 | 38 | public: 39 | // Called every frame 40 | virtual void Tick(float DeltaTime) override; 41 | }; 42 | -------------------------------------------------------------------------------- /Chapter12/Enemy.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "Enemy.h" 3 | #include "Perception/PawnSensingComponent.h" 4 | #include "GameFramework/CharacterMovementComponent.h" 5 | #include "EnemyController.h" 6 | #include "PangaeaAnimInstance.h" 7 | 8 | AEnemy::AEnemy() 9 | { 10 | PawnSensingComponent = CreateDefaultSubobject(TEXT("PawnSensor")); 11 | 12 | //static ConstructorHelpers::FObjectFinder blueprint_finder(TEXT("Blueprint'/Game/TopDown/Blueprints/BP_Hammer.BP_Hammer'")); 13 | //_WeaponClass = (UClass*)blueprint_finder.Object->GeneratedClass; 14 | } 15 | 16 | void AEnemy::BeginPlay() 17 | { 18 | Super::BeginPlay(); 19 | 20 | _Weapon = Cast(GetWorld()->SpawnActor(WeaponClass)); 21 | _Weapon->Holder = this; 22 | _Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, FName("hand_rSocket")); 23 | } 24 | 25 | void AEnemy::Tick(float DeltaTime) 26 | { 27 | Super::Tick(DeltaTime); 28 | 29 | if (_chasedTarget != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 30 | { 31 | auto enemyController = Cast(GetController()); 32 | enemyController->MakeAttackDecision(_chasedTarget); 33 | } 34 | } 35 | 36 | void AEnemy::Chase(APawn* targetPawn) 37 | { 38 | if (targetPawn != nullptr && _AnimInstance->State == ECharacterState::Locomotion) 39 | { 40 | auto enemyController = Cast(GetController()); 41 | enemyController->MoveToActor(targetPawn, 90.0f); 42 | } 43 | _chasedTarget = targetPawn; 44 | } 45 | 46 | void AEnemy::DieProcess() 47 | { 48 | Super::DieProcess(); 49 | _Weapon->Destroy(); 50 | } 51 | -------------------------------------------------------------------------------- /Chapter12/Enemy.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "PangaeaCharacter.h" 5 | #include "Weapon.h" 6 | 7 | #include "Enemy.generated.h" 8 | 9 | UCLASS() 10 | class PANGAEA_API AEnemy : public APangaeaCharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | AEnemy(); 16 | 17 | protected: 18 | virtual void BeginPlay() override; 19 | 20 | APawn* _chasedTarget = nullptr; 21 | AWeapon* _Weapon; 22 | //UClass* _WeaponClass; 23 | public: 24 | virtual void Tick(float DeltaTime) override; 25 | 26 | void DieProcess() override; 27 | 28 | UPROPERTY(EditAnywhere) 29 | TSubclassOf WeaponClass; 30 | 31 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Enemy") 32 | void Chase(APawn* targetPawn); 33 | private: 34 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true")) 35 | class UPawnSensingComponent* PawnSensingComponent; 36 | }; 37 | -------------------------------------------------------------------------------- /Chapter12/EnemyController.cpp: -------------------------------------------------------------------------------- 1 | #include "EnemyController.h" 2 | #include "Enemy.h" 3 | 4 | void AEnemyController::MakeAttackDecision(APawn* targetPawn) 5 | { 6 | auto enemy = Cast(GetPawn()); 7 | auto dist = FVector::Dist2D(targetPawn->GetActorLocation(), GetPawn()->GetTargetLocation()); 8 | 9 | if (dist <= enemy->AttackRange && enemy->CanAttack()) 10 | { 11 | StopMovement(); 12 | enemy->Attack_Broadcast_RPC(); 13 | } 14 | } -------------------------------------------------------------------------------- /Chapter12/EnemyController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "AIController.h" 5 | #include "EnemyController.generated.h" 6 | 7 | UCLASS() 8 | class PANGAEA_API AEnemyController : public AAIController 9 | { 10 | GENERATED_BODY() 11 | 12 | public: 13 | 14 | void MakeAttackDecision(APawn* targetPawn); //AI decision making. Called by PawnTick 15 | }; 16 | -------------------------------------------------------------------------------- /Chapter12/HealthBarWidget.cpp: -------------------------------------------------------------------------------- 1 | #include "HealthBarWidget.h" 2 | 3 | -------------------------------------------------------------------------------- /Chapter12/HealthBarWidget.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Components/ProgressBar.h" 5 | #include "Blueprint/UserWidget.h" 6 | #include "HealthBarWidget.generated.h" 7 | 8 | UCLASS() 9 | class PANGAEA_API UHealthBarWidget : public UUserWidget 10 | { 11 | GENERATED_BODY() 12 | 13 | 14 | public: 15 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (BindWidget)) 16 | UProgressBar* HealthProgressBar; 17 | }; 18 | -------------------------------------------------------------------------------- /Chapter12/Pangaea.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #include "Pangaea.h" 4 | #include "Modules/ModuleManager.h" 5 | 6 | IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, Pangaea, "Pangaea" ); 7 | 8 | DEFINE_LOG_CATEGORY(LogPangaea) 9 | -------------------------------------------------------------------------------- /Chapter12/Pangaea.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | DECLARE_LOG_CATEGORY_EXTERN(LogPangaea, Log, All); 8 | -------------------------------------------------------------------------------- /Chapter12/PangaeaAnimInstance.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaAnimInstance.h" 2 | #include "PangaeaCharacter.h" 3 | 4 | void UPangaeaAnimInstance::OnStateAnimationEnds() 5 | { 6 | if (State == ECharacterState::Attack) 7 | { 8 | State = ECharacterState::Locomotion; 9 | } 10 | else 11 | { 12 | auto character = Cast(GetOwningActor()); 13 | 14 | if (State == ECharacterState::Hit) 15 | { 16 | if (character->GetHealthPoints() > 0.0f) 17 | { 18 | State = ECharacterState::Locomotion; 19 | } 20 | else 21 | { 22 | State = ECharacterState::Die; 23 | } 24 | } 25 | else if (State == ECharacterState::Die) 26 | { 27 | character->DieProcess(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Chapter12/PangaeaAnimInstance.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "Animation/AnimInstance.h" 6 | #include "PangaeaAnimInstance.generated.h" 7 | 8 | UENUM(BlueprintType) 9 | enum class ECharacterState : uint8 10 | { 11 | Locomotion, 12 | Attack, 13 | Hit, 14 | Die 15 | }; 16 | 17 | 18 | UCLASS() 19 | class PANGAEA_API UPangaeaAnimInstance : public UAnimInstance 20 | { 21 | GENERATED_BODY() 22 | 23 | public: 24 | 25 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 26 | float Speed; 27 | 28 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PangaeaAnimInstance Params") 29 | ECharacterState State; 30 | 31 | UFUNCTION(BlueprintCallable) 32 | void OnStateAnimationEnds(); 33 | 34 | }; 35 | -------------------------------------------------------------------------------- /Chapter12/PangaeaCharacter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "HealthBarWidget.h" 5 | #include "GameFramework/Character.h" 6 | 7 | #include "PangaeaCharacter.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class APangaeaCharacter : public ACharacter 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaCharacter(); 16 | 17 | void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; 18 | 19 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 20 | int HealthPoints = 100; //the character's max health points 21 | 22 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 23 | float Strength = 5; //the character's attack strength 24 | 25 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 26 | float Armer = 1; //the character's defense armer 27 | 28 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 29 | float AttackRange = 200.0f; //the character's attack range 30 | 31 | UPROPERTY(EditAnywhere, Category = "Pangaea Character Params") 32 | float AttackInterval = 3.0f; //the character's attack invertval 33 | 34 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 35 | UUserWidget* HealthBarWidget; 36 | 37 | public: 38 | virtual void Tick(float DeltaTime) override; 39 | 40 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character", meta = (DisplayName = "Get HP")) 41 | int GetHealthPoints(); //get current health points 42 | 43 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 44 | bool IsKilled(); //check if the character has been killed 45 | 46 | UFUNCTION(BlueprintCallable, Category = "Pangaea|Character") 47 | bool CanAttack(); 48 | bool IsAttacking(); 49 | 50 | virtual void Attack(); 51 | virtual void Hit(int damage); 52 | virtual void DieProcess(); 53 | 54 | public: 55 | 56 | UFUNCTION(NetMultiCast, Reliable) 57 | void Attack_Broadcast_RPC(); 58 | 59 | protected: 60 | virtual void BeginPlay() override; 61 | 62 | class UPangaeaAnimInstance* _AnimInstance; 63 | 64 | float _AttackCountingDown; 65 | 66 | UPROPERTY(Replicatedusing = OnHealthPointsChanged) 67 | int _HealthPoints; 68 | 69 | UFUNCTION() 70 | void OnHealthPointsChanged(); 71 | }; 72 | 73 | -------------------------------------------------------------------------------- /Chapter12/PangaeaEditor.Target.cs: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.Collections.Generic; 5 | 6 | public class PangaeaEditorTarget : TargetRules 7 | { 8 | public PangaeaEditorTarget(TargetInfo Target) : base(Target) 9 | { 10 | Type = TargetType.Editor; 11 | DefaultBuildSettings = BuildSettingsVersion.V2; 12 | ExtraModuleNames.Add("Pangaea"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Chapter12/PangaeaGameInstance.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "PangaeaGameInstance.h" 3 | #include "Kismet/GameplayStatics.h" 4 | 5 | void UPangaeaGameInstance::StartTopdownListenServer() 6 | { 7 | auto world = GEngine->GetCurrentPlayWorld(); 8 | UGameplayStatics::OpenLevel(world, "TopDownMap", true, "?listen"); 9 | } 10 | 11 | void UPangaeaGameInstance::StartElvenRuinsListenServer() 12 | { 13 | auto world = GEngine->GetCurrentPlayWorld(); 14 | UGameplayStatics::OpenLevel(world, "ElvenRuins", true, "?listen"); 15 | } 16 | 17 | void UPangaeaGameInstance::JoinAsClient(FString IPAddress) 18 | { 19 | auto world = GEngine->GetCurrentPlayWorld(); 20 | UGameplayStatics::OpenLevel(world, *IPAddress, true, "?join"); 21 | } 22 | 23 | 24 | void UPangaeaGameInstance::LeaveGame() 25 | { 26 | auto world = GEngine->GetCurrentPlayWorld(); 27 | UGameplayStatics::OpenLevel(world, "LobbyMap"); 28 | } -------------------------------------------------------------------------------- /Chapter12/PangaeaGameInstance.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Engine/GameInstance.h" 5 | #include "PangaeaGameInstance.generated.h" 6 | 7 | 8 | UCLASS() 9 | class PANGAEA_API UPangaeaGameInstance : public UGameInstance 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | 15 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 16 | void StartTopdownListenServer(); 17 | 18 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 19 | void StartElvenRuinsListenServer(); 20 | 21 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 22 | void JoinAsClient(FString IPAddress); 23 | 24 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 25 | void LeaveGame(); 26 | 27 | }; 28 | -------------------------------------------------------------------------------- /Chapter12/PangaeaGameMode.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaGameMode.h" 2 | #include "PangaeaCharacter.h" 3 | #include "PangaeaPlayerController.h" 4 | #include "PangaeaGameState.h" 5 | #include "UObject/ConstructorHelpers.h" 6 | 7 | 8 | APangaeaGameMode::APangaeaGameMode() 9 | { 10 | // use our custom PlayerController class 11 | PlayerControllerClass = APangaeaPlayerController::StaticClass(); 12 | 13 | // set default pawn class to our Blueprinted character 14 | static ConstructorHelpers::FClassFinder PlayerPawnBPClass(TEXT("/Game/TopDown/Blueprints/BP_PlayerAvatar")); 15 | if (PlayerPawnBPClass.Class != nullptr) 16 | { 17 | DefaultPawnClass = PlayerPawnBPClass.Class; 18 | } 19 | 20 | // set default controller to our Blueprinted controller 21 | static ConstructorHelpers::FClassFinder PlayerControllerBPClass(TEXT("/Game/TopDown/Blueprints/BP_TopDownPlayerController")); 22 | if (PlayerControllerBPClass.Class != NULL) 23 | { 24 | PlayerControllerClass = PlayerControllerBPClass.Class; 25 | } 26 | 27 | GameStateClass = APangaeaGameState::StaticClass(); 28 | } 29 | 30 | APangaeaGameMode::~APangaeaGameMode() 31 | { 32 | AProjectile* fireball; 33 | while (!_FireballPool.IsEmpty() && _FireballPool.Dequeue(fireball)) 34 | { 35 | fireball->Destroy(); 36 | } 37 | _FireballPool.Empty(); 38 | } 39 | 40 | AProjectile* APangaeaGameMode::SpawnOrGetFireball(UClass* projectileClass) 41 | { 42 | AProjectile* fireball = nullptr; 43 | 44 | if (_FireballPool.IsEmpty()) 45 | { 46 | fireball = Cast(GetWorld()->SpawnActor(projectileClass)); 47 | } 48 | else 49 | { 50 | _FireballPool.Dequeue(fireball); 51 | fireball->Reset(); 52 | } 53 | 54 | return fireball; 55 | } 56 | 57 | void APangaeaGameMode::RecycleFireball(AProjectile* projectile) 58 | { 59 | if (projectile == nullptr) 60 | { 61 | return; 62 | } 63 | 64 | projectile->SetActorHiddenInGame(true); 65 | projectile->SetActorEnableCollision(false); 66 | projectile->SetActorTickEnabled(false); 67 | 68 | _FireballPool.Enqueue(projectile); 69 | } -------------------------------------------------------------------------------- /Chapter12/PangaeaGameMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "GameFramework/GameModeBase.h" 5 | #include "Projectile.h" 6 | 7 | #include "PangaeaGameMode.generated.h" 8 | 9 | UCLASS(minimalapi) 10 | class APangaeaGameMode : public AGameModeBase 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | APangaeaGameMode(); 16 | ~APangaeaGameMode(); 17 | 18 | AProjectile* SpawnOrGetFireball(UClass* ProjectileClass); 19 | void RecycleFireball(AProjectile* projectile); 20 | 21 | protected: 22 | 23 | TQueue _FireballPool; 24 | }; 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Chapter12/PangaeaGameState.cpp: -------------------------------------------------------------------------------- 1 | #include "PangaeaGameState.h" 2 | #include 3 | 4 | void APangaeaGameState::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const 5 | { 6 | Super::GetLifetimeReplicatedProps(OutLifetimeProps); 7 | DOREPLIFETIME(APangaeaGameState, Timer); 8 | } 9 | 10 | void APangaeaGameState::OnTimerChanged() 11 | { 12 | OnTimerChangedDelegate.Broadcast(Timer); 13 | } 14 | 15 | void APangaeaGameState::OnGameWin() 16 | { 17 | if (GetNetMode() == ENetMode::NM_ListenServer) 18 | { 19 | GameWin = true; 20 | } 21 | OnGameWinLoseDelegate.Broadcast(true); 22 | } 23 | -------------------------------------------------------------------------------- /Chapter12/PangaeaGameState.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | #include "CoreMinimal.h" 5 | #include "GameFramework/GameStateBase.h" 6 | #include "PangaeaGameState.generated.h" 7 | 8 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnTimerChangedDelegate, float, Timer); 9 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGameWinLoseDelegate, bool, Win); 10 | 11 | UCLASS() 12 | class PANGAEA_API APangaeaGameState : public AGameStateBase 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | 18 | void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; 19 | 20 | public: 21 | 22 | UPROPERTY(BlueprintAssignable, Category = "Pangaea") 23 | FOnTimerChangedDelegate OnTimerChangedDelegate; 24 | 25 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 26 | void OnTimerChanged(); 27 | 28 | UPROPERTY(BlueprintReadWrite, ReplicatedUsing = OnTimerChanged, Category = "Pangaea") 29 | float Timer = 0; 30 | 31 | UPROPERTY(BlueprintAssignable, Category = "Pangaea") 32 | FOnGameWinLoseDelegate OnGameWinLoseDelegate; 33 | 34 | UFUNCTION(BlueprintCallable, Category = "Pangaea") 35 | void OnGameWin(); 36 | 37 | 38 | UPROPERTY(BlueprintReadWrite, ReplicatedUsing = OnGameWin, Category = "Pangaea") 39 | bool GameWin; 40 | 41 | }; 42 | -------------------------------------------------------------------------------- /Chapter12/PangaeaPlayerController.h: -------------------------------------------------------------------------------- 1 | // Copyright Epic Games, Inc. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Templates/SubclassOf.h" 7 | #include "GameFramework/PlayerController.h" 8 | #include "PangaeaPlayerController.generated.h" 9 | 10 | /** Forward declaration to improve compiling times */ 11 | class UNiagaraSystem; 12 | 13 | UCLASS() 14 | class APangaeaPlayerController : public APlayerController 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APangaeaPlayerController(); 20 | 21 | /** Time Threshold to know if it was a short press */ 22 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 23 | float ShortPressThreshold; 24 | 25 | /** FX Class that we will spawn when clicking */ 26 | UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input) 27 | UNiagaraSystem* FXCursor; 28 | 29 | protected: 30 | /** True if the controlled character should navigate to the mouse cursor. */ 31 | uint32 bMoveToMouseCursor : 1; 32 | 33 | // Begin PlayerController interface 34 | virtual void PlayerTick(float DeltaTime) override; 35 | virtual void SetupInputComponent() override; 36 | // End PlayerController interface 37 | 38 | /** Input handlers for SetDestination action. */ 39 | void OnSetDestinationPressed(); 40 | void OnSetDestinationReleased(); 41 | void OnTouchPressed(const ETouchIndex::Type FingerIndex, const FVector Location); 42 | void OnTouchReleased(const ETouchIndex::Type FingerIndex, const FVector Location); 43 | 44 | /** Input Handler for the Attack action. */ 45 | void OnAttackPressed(); 46 | private: 47 | bool bInputPressed; // Input is bring pressed 48 | bool bIsTouch; // Is it a touch device 49 | float FollowTime; // For how long it has been pressed 50 | }; 51 | 52 | 53 | -------------------------------------------------------------------------------- /Chapter12/PlayerAvatar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "Camera/CameraComponent.h" 5 | #include "GameFramework/SpringArmComponent.h" 6 | #include "PangaeaCharacter.h" 7 | #include "Weapon.h" 8 | 9 | #include "PlayerAvatar.generated.h" 10 | 11 | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnPlayerIsKilledDelegate); 12 | 13 | UCLASS(Blueprintable) 14 | class PANGAEA_API APlayerAvatar : public APangaeaCharacter 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | APlayerAvatar(); 20 | 21 | 22 | protected: 23 | virtual void BeginPlay() override; 24 | 25 | public: 26 | virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; 27 | 28 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 29 | void AttachWeapon(AWeapon* Weapon); 30 | 31 | UFUNCTION(BlueprintCallable, Category = "Pangaea|PlayerAvatar") 32 | void DropWeapon(); 33 | 34 | FORCEINLINE class UCameraComponent* GetCameraComponet() const { return _CameraComponent; } 35 | FORCEINLINE class USpringArmComponent* GetSringArmComponet() const { return _SpringArmComponent; } 36 | 37 | UFUNCTION(Server, Reliable) 38 | void Attack_RPC(); 39 | 40 | UPROPERTY(BlueprintAssignable, Category = "Pangaea|PlayerAvatar") 41 | FOnPlayerIsKilledDelegate OnPlayerIsKilledDelegate; 42 | 43 | void DieProcess() override; 44 | 45 | private: 46 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 47 | USpringArmComponent* _SpringArmComponent; 48 | 49 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera", meta = (AllowPrivateAccess = "true")) 50 | UCameraComponent* _CameraComponent; 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /Chapter12/Projectile.cpp: -------------------------------------------------------------------------------- 1 | #include "Projectile.h" 2 | 3 | #include "Kismet/GameplayStatics.h" 4 | #include "PangaeaGameMode.h" 5 | #include "PlayerAvatar.h" 6 | 7 | AProjectile::AProjectile() 8 | { 9 | PrimaryActorTick.bCanEverTick = true; 10 | bReplicates = true; 11 | 12 | _MeshComponent = CreateDefaultSubobject(TEXT("Static Mesh")); 13 | SetRootComponent(_MeshComponent); 14 | } 15 | 16 | void AProjectile::BeginPlay() 17 | { 18 | Super::BeginPlay(); 19 | _PangaeaGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld())); 20 | Reset(); 21 | } 22 | 23 | void AProjectile::Tick(float DeltaTime) 24 | { 25 | Super::Tick(DeltaTime); 26 | 27 | if (GetNetMode() == NM_Client) 28 | { 29 | return; 30 | } 31 | 32 | if (_LifeCountingDown > 0.0f) 33 | { 34 | FVector currentLocation = GetActorLocation(); 35 | FVector vel = GetActorRotation().RotateVector(FVector::ForwardVector) * Speed * DeltaTime; 36 | FVector nextLocation = currentLocation + vel; 37 | SetActorLocation(nextLocation); 38 | 39 | //Ray cast check 40 | FHitResult hitResult; 41 | FCollisionObjectQueryParams objCollisionQueryParams; 42 | objCollisionQueryParams.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); 43 | 44 | if (GetWorld()->LineTraceSingleByObjectType(hitResult, currentLocation, nextLocation, objCollisionQueryParams)) 45 | { 46 | auto playerAvatar = Cast(hitResult.GetActor()); 47 | if (playerAvatar != nullptr) 48 | { 49 | playerAvatar->Hit(Damage); 50 | _PangaeaGameMode->RecycleFireball(this); 51 | 52 | } 53 | } 54 | 55 | _LifeCountingDown -= DeltaTime; 56 | } 57 | else 58 | { 59 | _PangaeaGameMode->RecycleFireball(this); 60 | } 61 | } 62 | 63 | void AProjectile::Reset() 64 | { 65 | _LifeCountingDown = Lifespan; 66 | SetActorHiddenInGame(false); 67 | SetActorEnableCollision(true); 68 | SetActorTickEnabled(true); 69 | } -------------------------------------------------------------------------------- /Chapter12/Projectile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Components/BoxComponent.h" 4 | #include "Components/StaticMeshComponent.h" 5 | #include "GameFramework/Actor.h" 6 | 7 | #include "Projectile.generated.h" 8 | 9 | UCLASS(Blueprintable) 10 | class PANGAEA_API AProjectile : public AActor 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | AProjectile(); 16 | 17 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 18 | float Speed = 100.0f; //the projectile's speed 19 | 20 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 21 | float Lifespan = 5.0f; //the projectile's lifespan 22 | 23 | UPROPERTY(EditAnywhere, Category = "Projectile Params") 24 | float Damage = 30.0f; //the projectile's damage points 25 | 26 | protected: 27 | virtual void BeginPlay() override; 28 | 29 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Visual, meta = (AllowPrivateAccess = "true")) 30 | UStaticMeshComponent* _MeshComponent; 31 | 32 | float _LifeCountingDown; 33 | class APangaeaGameMode* _PangaeaGameMode; 34 | public: 35 | virtual void Tick(float DeltaTime) override; 36 | 37 | FORCEINLINE UStaticMeshComponent* GetMeshComponent() const { return _MeshComponent; } 38 | 39 | void Reset(); 40 | }; 41 | -------------------------------------------------------------------------------- /Chapter12/Weapon.cpp: -------------------------------------------------------------------------------- 1 | #include "Weapon.h" 2 | #include "PangaeaCharacter.h" 3 | #include "PlayerAvatar.h" 4 | #include "DefenseTower.h" 5 | 6 | AWeapon::AWeapon() 7 | { 8 | PrimaryActorTick.bCanEverTick = true; 9 | bReplicates = true; 10 | SetReplicateMovement(true); 11 | 12 | _StaticMesh = CreateDefaultSubobject(TEXT("Static Mesh")); 13 | SetRootComponent(_StaticMesh); 14 | } 15 | 16 | void AWeapon::BeginPlay() 17 | { 18 | Super::BeginPlay(); 19 | 20 | OnActorBeginOverlap.AddDynamic(this, &AWeapon::OnWeaponBeginOverlap); 21 | } 22 | 23 | void AWeapon::Tick(float DeltaTime) 24 | { 25 | Super::Tick(DeltaTime); 26 | 27 | if (Holder == nullptr) 28 | { 29 | FQuat rotQuat = FQuat(FRotator(0.0f, 300.0f * DeltaTime, 0.0f)); 30 | AddActorLocalRotation(rotQuat); 31 | } 32 | } 33 | 34 | 35 | void AWeapon::OnWeaponBeginOverlap(AActor* OverlappedActor, AActor* OtherActor) 36 | { 37 | //GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Orange, TEXT("Weapon overlapped")); 38 | //UE_LOG(LogTemp, Log, TEXT("Weapon overlapped")); 39 | 40 | auto character = Cast(OtherActor); 41 | 42 | if (character == nullptr) 43 | { 44 | return; 45 | } 46 | 47 | if (Holder == nullptr) 48 | { 49 | auto playerAvatar = Cast(character); 50 | 51 | if (playerAvatar != nullptr) 52 | { 53 | Holder = character; 54 | playerAvatar->DropWeapon(); 55 | playerAvatar->AttachWeapon(this); 56 | } 57 | } 58 | else if (GetNetMode() == ENetMode::NM_ListenServer && 59 | character != Holder && 60 | IsWithinAttackRange(0.0f, OtherActor) && 61 | character->CanBeDamaged() && 62 | Holder->IsAttacking()) 63 | { 64 | character->Hit(Holder->Strength); 65 | 66 | if (character->IsA(APlayerAvatar::StaticClass())) 67 | { 68 | GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Red, TEXT("Hit PlayerAvatar")); 69 | UE_LOG(LogTemp, Log, TEXT("Hit PlayerAvatar")); 70 | } 71 | else 72 | { 73 | GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Cyan, TEXT("Hit Enemy")); 74 | UE_LOG(LogTemp, Log, TEXT("Hit Enemy")); 75 | } 76 | } 77 | } 78 | 79 | 80 | bool AWeapon::IsWithinAttackRange(float AttackRange, AActor* Target) 81 | { 82 | float distance = FVector::Distance(Target->GetActorLocation(), GetActorLocation()); 83 | return (AttackRange <= 0.0f || distance <= AttackRange); 84 | } 85 | -------------------------------------------------------------------------------- /Chapter12/Weapon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CoreMinimal.h" 4 | #include "GameFramework/Actor.h" 5 | #include "GameFramework/Character.h" 6 | #include "Components/SphereComponent.h" 7 | #include "Weapon.generated.h" 8 | 9 | UCLASS() 10 | class PANGAEA_API AWeapon : public AActor 11 | { 12 | GENERATED_BODY() 13 | 14 | public: 15 | // Sets default values for this actor's properties 16 | AWeapon(); 17 | 18 | UPROPERTY(VisibleAnywhere, BlueprintReadWrite) 19 | class APangaeaCharacter* Holder = nullptr; 20 | 21 | UPROPERTY(EditAnywhere, Category = "Weapon Params") 22 | float Strength = 10; 23 | 24 | protected: 25 | virtual void BeginPlay() override; 26 | 27 | UPROPERTY(VisibleAnywhere, BlueprintReadOnly) 28 | UStaticMeshComponent* _StaticMesh; 29 | 30 | UFUNCTION() 31 | void OnWeaponBeginOverlap(AActor* OverlappedActor, AActor* OtherActor); 32 | 33 | public: 34 | virtual void Tick(float DeltaTime) override; 35 | bool IsWithinAttackRange(float AttackRange, AActor* Target); 36 | }; 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /PangaeaAssets/DefenseTower/DefenseTower.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/DefenseTower/DefenseTower.FBX -------------------------------------------------------------------------------- /PangaeaAssets/DefenseTower/DefenseTower_c.TGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/DefenseTower/DefenseTower_c.TGA -------------------------------------------------------------------------------- /PangaeaAssets/Enemy/Enemy.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Enemy/Enemy.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Enemy/T_Enemy_COL.tga: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Enemy/T_Enemy_COL.tga -------------------------------------------------------------------------------- /PangaeaAssets/Enemy/T_Enemy_NOR.TGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Enemy/T_Enemy_NOR.TGA -------------------------------------------------------------------------------- /PangaeaAssets/Hero/Hero.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/Hero.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Hero/Hero_Anim_Attack.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/Hero_Anim_Attack.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Hero/Hero_Anim_Die.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/Hero_Anim_Die.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Hero/Hero_Anim_Hit.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/Hero_Anim_Hit.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Hero/Hero_Anim_Idle.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/Hero_Anim_Idle.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Hero/Hero_Anim_Run.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/Hero_Anim_Run.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Hero/Hero_Anim_Walk.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/Hero_Anim_Walk.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Hero/T_CharA_COL.TGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/T_CharA_COL.TGA -------------------------------------------------------------------------------- /PangaeaAssets/Hero/T_CharA_NOR.TGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Hero/T_CharA_NOR.TGA -------------------------------------------------------------------------------- /PangaeaAssets/LobbyBG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/LobbyBG.png -------------------------------------------------------------------------------- /PangaeaAssets/Weapons/Axe/Axe.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Weapons/Axe/Axe.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Weapons/Axe/Axe_c.TGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Weapons/Axe/Axe_c.TGA -------------------------------------------------------------------------------- /PangaeaAssets/Weapons/Hammer/Hammer.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Weapons/Hammer/Hammer.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Weapons/Hammer/hammer_c.TGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Weapons/Hammer/hammer_c.TGA -------------------------------------------------------------------------------- /PangaeaAssets/Weapons/Sword/Sword.FBX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Weapons/Sword/Sword.FBX -------------------------------------------------------------------------------- /PangaeaAssets/Weapons/Sword/Sword_c.TGA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/Unreal-Engine-5-Game-Development-with-C-Scripting/953bc1a4bb6c466a3b7c1c373e49bd27a1fc22d9/PangaeaAssets/Weapons/Sword/Sword_c.TGA -------------------------------------------------------------------------------- /Readme.txt: -------------------------------------------------------------------------------- 1 | \Chapter 01 2 | \Chapter 02 3 | MyCPP_01 4 | \Chapter 03 5 | MyCPP_02 6 | MyCPP_03 7 | MyCPP_04 8 | MyCPP_05 9 | \Chapter 04 10 | \Chapter 05 11 | \Chapter 06 12 | \Chapter 07 13 | \Chapter 08 14 | \Chapter 09 15 | \Chapter 10 16 | \Chapter 11 17 | \Chapter 12 18 | 19 | --------------------------------------------------------------------------------