Merge remote-tracking branch 'origin/master'

# Conflicts:
#	Binaries/Win64/UnrealEditor-LegumeMix.exp
#	Binaries/Win64/UnrealEditor-LegumeMix.pdb
#	Content/Legumix/BP_GameMode.uasset
This commit is contained in:
Emilie Schott 2025-01-24 14:37:42 +01:00
commit 51f7906f66
91 changed files with 1226 additions and 120 deletions

View File

@ -21,18 +21,6 @@
"BuildId": "37670630"
},
"BuildProducts": [
{
"Path": "$(ProjectDir)/Binaries/Win64/UnrealEditor-LegumeMix.dll",
"Type": "DynamicLibrary"
},
{
"Path": "$(ProjectDir)/Binaries/Win64/UnrealEditor-LegumeMix.pdb",
"Type": "SymbolFile"
},
{
"Path": "$(ProjectDir)/Binaries/Win64/UnrealEditor.modules",
"Type": "RequiredResource"
},
{
"Path": "$(EngineDir)/Binaries/ThirdParty/USD/UsdResources/Win64/plugins/ar/resources/plugInfo.json",
"Type": "RequiredResource"
@ -4816,13 +4804,21 @@
{
"Path": "$(EngineDir)/Plugins/XGEController/Binaries/Win64/UnrealEditor.modules",
"Type": "RequiredResource"
},
{
"Path": "$(ProjectDir)/Binaries/Win64/UnrealEditor-LegumeMix.dll",
"Type": "DynamicLibrary"
},
{
"Path": "$(ProjectDir)/Binaries/Win64/UnrealEditor-LegumeMix.pdb",
"Type": "SymbolFile"
},
{
"Path": "$(ProjectDir)/Binaries/Win64/UnrealEditor.modules",
"Type": "RequiredResource"
}
],
"RuntimeDependencies": [
{
"Path": "$(ProjectDir)/LegumeMix.uproject",
"Type": "UFS"
},
{
"Path": "$(EngineDir)/Binaries/ThirdParty/DbgHelp/dbghelp.dll",
"Type": "NonUFS"
@ -30546,6 +30542,10 @@
{
"Path": "$(EngineDir)/Plugins/XGEController/XGEController.uplugin",
"Type": "UFS"
},
{
"Path": "$(ProjectDir)/LegumeMix.uproject",
"Type": "UFS"
}
],
"BuildPlugins": [

BIN
Binaries/Win64/UnrealEditor-LegumeMix.exp (Stored with Git LFS)

Binary file not shown.

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7a53ca02ff4ea16ec35044f5ff34db3b66eed5064e880795f22c4e00262fc765
size 60215296
oid sha256:953b61f6b9c8407afb0be82725d98136bad5a38c72477cc8992dfc8ddf979d68
size 60887040

File diff suppressed because one or more lines are too long

View File

@ -1,8 +1,9 @@
[/Script/EngineSettings.GameMapsSettings]
GameDefaultMap=/Engine/Maps/Templates/OpenWorld.OpenWorld
GameDefaultMap=/Game/Legumix/Levels/LVL_GYM_00.LVL_GYM_00
GlobalDefaultGameMode=/Game/Legumix/BP_GameMode.BP_GameMode_C
EditorStartupMap=/Game/Legumix/Levels/LVL_GYM_00.LVL_GYM_00
[/Script/Engine.RendererSettings]
r.AllowStaticLighting=False
@ -91,3 +92,69 @@ ConnectionType=USBOnly
bUseManualIPAddress=False
ManualIPAddress=
[/Script/Engine.CollisionProfile]
-Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision",bCanModify=False)
-Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
-Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
-Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
-Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
-Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.",bCanModify=False)
-Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ",bCanModify=False)
-Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ",bCanModify=False)
-Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic",Response=ECR_Block),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.",bCanModify=False)
-Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.",bCanModify=False)
-Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors",bCanModify=False)
-Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors",bCanModify=False)
-Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.",bCanModify=False)
-Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.",bCanModify=False)
-Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.",bCanModify=False)
-Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.",bCanModify=False)
-Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.",bCanModify=False)
-Profiles=(Name="UI",CollisionEnabled=QueryOnly,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Block),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ",bCanModify=False)
+Profiles=(Name="NoCollision",CollisionEnabled=NoCollision,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="No collision")
+Profiles=(Name="BlockAll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=,HelpMessage="WorldStatic object that blocks all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="OverlapAll",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="BlockAllDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=,HelpMessage="WorldDynamic object that blocks all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="OverlapAllDynamic",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that overlaps all actors by default. All new custom channels will use its own default response. ")
+Profiles=(Name="IgnoreOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that ignores Pawn and Vehicle. All other channels will be set to default.")
+Profiles=(Name="OverlapOnlyPawn",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Pawn",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that overlaps Pawn, Camera, and Vehicle. All other channels will be set to default. ")
+Profiles=(Name="Pawn",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object. Can be used for capsule of any playerable character or AI. ")
+Profiles=(Name="Spectator",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="WorldStatic"),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Pawn object that ignores all other actors except WorldStatic.")
+Profiles=(Name="CharacterMesh",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="Pawn",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Pawn object that is used for Character Mesh. All other channels will be set to default.")
+Profiles=(Name="PhysicsActor",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=,HelpMessage="Simulating actors")
+Profiles=(Name="Destructible",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Destructible",CustomResponses=,HelpMessage="Destructible actors")
+Profiles=(Name="InvisibleWall",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldStatic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldStatic object that is invisible.")
+Profiles=(Name="InvisibleWallDynamic",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Visibility",Response=ECR_Ignore)),HelpMessage="WorldDynamic object that is invisible.")
+Profiles=(Name="Trigger",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldDynamic object that is used for trigger. All other channels will be set to default.")
+Profiles=(Name="Ragdoll",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="PhysicsBody",CustomResponses=((Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore)),HelpMessage="Simulating Skeletal Mesh Component. All other channels will be set to default.")
+Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.")
+Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility"),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ")
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=True,bStaticObject=False,Name="Bullet")
+EditProfiles=(Name="NoCollision",CustomResponses=((Channel="Bullet",Response=ECR_Ignore)))
+EditProfiles=(Name="OverlapAll",CustomResponses=((Channel="Bullet",Response=ECR_Overlap)))
+EditProfiles=(Name="CharacterMesh",CustomResponses=((Channel="Bullet",Response=ECR_Ignore)))
+EditProfiles=(Name="OverlapAllDynamic",CustomResponses=((Channel="Bullet",Response=ECR_Overlap)))
+EditProfiles=(Name="OverlapOnlyPawn",CustomResponses=((Channel="Bullet",Response=ECR_Ignore)))
+EditProfiles=(Name="Pawn",CustomResponses=((Channel="Bullet",Response=ECR_Ignore)))
+EditProfiles=(Name="Trigger",CustomResponses=((Channel="Bullet",Response=ECR_Overlap)))
+EditProfiles=(Name="Ragdoll",CustomResponses=((Channel="Bullet",Response=ECR_Ignore)))
+EditProfiles=(Name="UI",CustomResponses=((Channel="Bullet",Response=ECR_Ignore)))
-ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
-ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
-ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
-ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor")
-ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic")
+ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
+ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
+ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
+ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor")
+ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic")
-CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic")
-CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
-CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
-CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")
+CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic")
+CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic")
+CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle")
+CollisionChannelRedirects=(OldName="PawnMovement",NewName="Pawn")

BIN
Content/Legumix/Ennemy/BP_Dummy.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Ennemy/BP_HealthComponent.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Ennemy/BP_HitBox_Body.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Ennemy/BP_HitBox_Head.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Levels/Assets/Carott_Container.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Legumix/Levels/Assets/Radish_Container.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Levels/LVL_00.umap (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Levels/LVL_GYM_00.umap (Stored with Git LFS)

Binary file not shown.

BIN
Content/Legumix/Levels/T_GabaritChecker_Gray.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Levels/T_GabaritChecker_Gray_Mat.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Legumix/Player/BP_Play.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Player/BP_Player.uasset (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

BIN
Content/Legumix/Weapon/Ammo/DT_Munitions.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/BP_Bazoucorn.uasset (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Legumix/Weapon/Revolver/BP_Revolver.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Revolver/C_Falloff_Revolver.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Revolver/Pistolet.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/Legumix/Weapon/Revolver/Revolvert.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Shotgun/02_-_Default.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Shotgun/BP_Shotgun.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Shotgun/C_Falloff_Shotgun.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Shotgun/Pistolet.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Shotgun/Plane002.uasset (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Legumix/Weapon/Shotgun/ShotgunFirePlaceholder.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

BIN
Content/Legumix/Weapon/WeaponSwitchPlaceholder.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,9 +1,8 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon/LMAmmo.h"
#include "Ammo/LMAmmo.h"
#include "Components/BoxComponent.h"
#include "Components/SphereComponent.h"
#include "Player/LMPlayer.h"

View File

@ -0,0 +1,62 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Player/LMHealthComponent.h"
#include "Player/LMHitBox.h"
ULMHealthComponent::ULMHealthComponent()
{
PrimaryComponentTick.bCanEverTick = true;
}
void ULMHealthComponent::BeginPlay()
{
Super::BeginPlay();
if (bMaxHealthOnStart)
Health = MaxHealth;
RegisterHitBoxes();
}
void ULMHealthComponent::RegisterHitBoxes()
{
GetOwner()->GetComponents<ULMHitBox>(HitBoxes);
for (const auto HitBox : HitBoxes)
{
HitBox->OnHitBoxHit.AddUniqueDynamic(this, &ULMHealthComponent::HitBoxHit);
}
}
void ULMHealthComponent::TakeDamage_Implementation(const float Damage)
{
if (Damage <= 0.0f)
return;
OnHit(Damage);
OnHealthChanged.Broadcast(Health, Damage);
if (Health <= 0.0f)
Kill();
}
void ULMHealthComponent::OnHit_Implementation(const float Damage)
{
Health = FMath::Clamp(Health - Damage, 0.0f, MaxHealth);
}
void ULMHealthComponent::Kill()
{
OnKill();
OnDeath.Broadcast();
}
void ULMHealthComponent::HitBoxHit(ULMHitBox* HitBox, float Damage)
{
TakeDamage(Damage);
}

View File

@ -0,0 +1,38 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Player/LMHitBox.h"
#include "Player/LMBulletInfo.h"
ULMHitBox::ULMHitBox()
{
PrimaryComponentTick.bCanEverTick = true;
}
void ULMHitBox::OnHit(const FLMBulletInfo& BulletInfo)
{
const float Damage = BulletInfo.Damage;
const double Distance = FVector::Distance(BulletInfo.Origin, GetComponentLocation());
const float TotalDamage = CalculateDamage(Damage, Distance, BulletInfo.Falloff, BulletInfo.MaxDistance);
OnHitBoxHit.Broadcast(this, TotalDamage);
}
float ULMHitBox::CalculateDamage_Implementation(const float Damage, const float Distance, UCurveFloat* Falloff, const float MaxDistance)
{
const float Absorption = Damage - FlatDamageAbsorption;
const float FalloffModifier = Falloff->GetFloatValue(Distance / MaxDistance);
UE_LOG(LogTemp, Display, TEXT("Falloff : %f"), FalloffModifier);
const float FalloffDamage = Absorption * FalloffModifier;
UE_LOG(LogTemp, Display, TEXT("Damage With Fallof: %f"), FalloffDamage)
const float FinalDamage = FalloffDamage * DamageModifier;
UE_LOG(LogTemp, Display, TEXT("Final Damages: %f"), FinalDamage)
return FinalDamage;
}

View File

@ -3,8 +3,12 @@
#include "Player/LMPlayer.h"
#include "KismetTraceUtils.h"
#include "LMUtils.h"
#include "Camera/CameraComponent.h"
#include "Weapon/LMAmmo.h"
#include "Ammo/LMAmmo.h"
#include "Player/LMBulletInfo.h"
#include "Player/LMHitBox.h"
#include "Weapon/LMWeaponManager.h"
ALMPlayer::ALMPlayer()
@ -17,8 +21,10 @@ ALMPlayer::ALMPlayer()
Camera->bUsePawnControlRotation = true;
Camera->SetRelativeLocation(FVector(20, 0, 90));
WeaponSkeletalMeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Weapon Mesh"));
WeaponSkeletalMeshComponent->SetupAttachment(Camera);
ArmsMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Arms Mesh"));
ArmsMesh->SetupAttachment(Camera);
SpreadStream = FRandomStream(FMath::Rand());
}
// Called when the game starts or when spawned
@ -38,6 +44,16 @@ void ALMPlayer::PickUpAmmo(ALMAmmo* Ammo)
WeaponManager->AddAmmoType(Ammo->GetAmmoType(), Ammo->GetAmmoAmount());
}
int ALMPlayer::GetAmmoCount(const EAmmoType AmmoType) const
{
return WeaponManager->GetAmmoCount(AmmoType);
}
int ALMPlayer::RemoveAmmo(const EAmmoType AmmoType, const int Count) const
{
return WeaponManager->RemoveAmmo(AmmoType, Count);
}
void ALMPlayer::SetWeaponManager(ULMWeaponManager* Manager)
{
UE_LOG(LogTemp, Warning, TEXT("Set weapon manager"))
@ -48,16 +64,61 @@ void ALMPlayer::SetWeaponManager(ULMWeaponManager* Manager)
}
WeaponManager = Manager;
WeaponManager->Initialize(WeaponSkeletalMeshComponent);
WeaponManager->Initialize(ArmsMesh);
}
// Called every frame
void ALMPlayer::PlayAnimation(UAnimMontage* Animation)
{
}
void ALMPlayer::FireBullets(const FLMBulletInfo Settings)
{
FVector EndLocation;
FVector ShotVector;
FHitResult OutHit = FHitResult();
DrawDebugLine(GetWorld(), Settings.Origin, Settings.Origin + (Settings.Direction * Settings.MaxDistance), FColor::Blue, false, 2.f);
for (int Shots = 0; Shots < Settings.BulletCount; Shots++)
{
ShotVector = UKismetMathLibrary::RandomUnitVectorInConeInDegreesFromStream(SpreadStream, Settings.Direction, Settings.Spread);
EndLocation = Settings.Origin + (ShotVector * Settings.MaxDistance);
const bool HasHit = GetWorld()->LineTraceSingleByChannel(OutHit, Settings.Origin, EndLocation, TRACE_BULLET);
DrawDebugLineTraceSingle(GetWorld(), Settings.Origin, EndLocation, EDrawDebugTrace::ForDuration, HasHit, OutHit, FColor::Green, FColor::Red, 2.f);
if (!HasHit)
continue;
FString Hit = FString::Printf(TEXT("Hit %s"), *OutHit.Component->GetName());
// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 2.f, FColor::Red, Hit);
UE_LOG(LogTemp, Display, TEXT("%s"), *Hit);
if (ULMHitBox* HitBox = Cast<ULMHitBox>(OutHit.Component))
{
UE_LOG(LogTemp, Warning, TEXT("Hit Hitbox"));
HitBox->OnHit(Settings);
}
}
}
FVector ALMPlayer::GetWeaponFiringOrigin() const
{
if (!Camera)
{
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 10.f, FColor::Silver, TEXT("No camera ???"));
return FVector::ZeroVector;
}
return Camera->GetComponentTransform().GetLocation();
}
FVector ALMPlayer::GetAimVector() const { return Camera->GetForwardVector(); }
void ALMPlayer::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ALMPlayer::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);

View File

@ -0,0 +1,46 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon/LMRevolver.h"
#include "Player/LMBulletInfo.h"
#include "Player/LMPlayer.h"
ALMRevolver::ALMRevolver()
{
PrimaryActorTick.bCanEverTick = true;
}
void ALMRevolver::PrimaryFire()
{
if (!Player)
return;
State = EWeaponState::EWS_Firing;
if (ClipAmmo <= 0)
{
if (!Reload())
{
PlaySound(DryFireSound, true);
GetWorldTimerManager().SetTimer(FireTimer, this, &ALMRevolver::AllowRefire, RefireDelay / 2);
}
return;
}
PlaySound(FireSound, true);
PlayAnimation(PrimaryFireAnimation);
const FVector Origin = Player->GetWeaponFiringOrigin();
const FVector Direction = Player->GetAimVector();
ClipAmmo--;
FLMBulletInfo ShotInfo = FLMBulletInfo(1, Origin, Direction, WeaponSpread, MaxDistance, DamageFalloff, AmmoType, Damage);
Player->FireBullets(ShotInfo);
GetWorldTimerManager().SetTimer(FireTimer, this, &ALMRevolver::AllowRefire, RefireDelay);
}

View File

@ -0,0 +1,45 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon/LMShotgun.h"
#include "Player/LMBulletInfo.h"
#include "Player/LMPlayer.h"
ALMShotgun::ALMShotgun()
{
PrimaryActorTick.bCanEverTick = true;
}
void ALMShotgun::PrimaryFire()
{
if (!Player)
return;
State = EWeaponState::EWS_Firing;
if (ClipAmmo <= 0)
{
if (!Reload())
{
PlaySound(DryFireSound, true);
GetWorldTimerManager().SetTimer(FireTimer, this, &ALMShotgun::AllowRefire, RefireDelay / 2);
}
return;
}
PlaySound(FireSound, true);
PlayAnimation(PrimaryFireAnimation);
const FVector Origin = Player->GetWeaponFiringOrigin();
const FVector Direction = Player->GetAimVector();
ClipAmmo--;
FLMBulletInfo ShotInfo = FLMBulletInfo(PelletCount, Origin, Direction, WeaponSpread, MaxDistance, DamageFalloff, AmmoType, Damage);
Player->FireBullets(ShotInfo);
GetWorldTimerManager().SetTimer(FireTimer, this, &ALMShotgun::AllowRefire, RefireDelay);
}

View File

@ -0,0 +1,115 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "Weapon/LMWeaponBase.h"
#include "Components/AudioComponent.h"
#include "Player/LMPlayer.h"
ALMWeaponBase::ALMWeaponBase()
{
PrimaryActorTick.bCanEverTick = true;
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
AudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("Audio"));
AudioComponent->SetupAttachment(RootComponent);
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
WeaponMesh->SetupAttachment(RootComponent);
WeaponSocket = FName();
}
void ALMWeaponBase::BeginPlay()
{
Super::BeginPlay();
}
void ALMWeaponBase::Setup(USkeletalMeshComponent* Mesh, AActor* CharOwner)
{
SetActorHiddenInGame(true);
FAttachmentTransformRules Rules = FAttachmentTransformRules(EAttachmentRule::SnapToTarget,
EAttachmentRule::KeepRelative,
EAttachmentRule::KeepRelative,
false);
AttachToComponent(Mesh, Rules);
Player = Cast<ALMPlayer>(CharOwner);
}
void ALMWeaponBase::OnEquip_Implementation()
{
PlaySound(EquipSound);
}
bool ALMWeaponBase::Reload()
{
return DefaultReload();
}
void ALMWeaponBase::PrimaryFire()
{
}
void ALMWeaponBase::PlaySound(USoundWave* Sound, const bool Replacing)
{
if (AudioComponent->IsPlaying() && !Replacing)
return;
AudioComponent->Stop();
AudioComponent->SetSound(Sound);
AudioComponent->Play();
}
void ALMWeaponBase::PlayAnimation(UAnimMontage* Animation)
{
UAnimInstance* AnimInstance = WeaponMesh->GetAnimInstance();
if (Animation && AnimInstance)
{
AnimInstance->Montage_Play(Animation);
}
}
bool ALMWeaponBase::DefaultReload()
{
if (State != EWeaponState::EWS_Idle)
return false;
const int AmmoCount = Player->GetAmmoCount(AmmoType);
if (AmmoCount <= 0)
return false;
if (ClipAmmo >= MaxClip)
return false;
PlaySound(ReloadSound, true);
PlayAnimation(ReloadAnimation);
State = EWeaponState::EWS_Reloading;
// TODO: Use Animations
OnDefaultReload();
GetWorldTimerManager().SetTimer(ReloadTimer, this, &ALMWeaponBase::AllowRefire, ReloadDelay);
return true;
}
void ALMWeaponBase::AllowRefire()
{
// TODO : improve this
if (FireTimer.IsValid())
GetWorldTimerManager().ClearTimer(FireTimer);
else if (ReloadTimer.IsValid())
GetWorldTimerManager().ClearTimer(ReloadTimer);
State = EWeaponState::EWS_Idle;
if (ClipAmmo <= 0)
{
Reload();
}
}

View File

@ -1 +0,0 @@
#include "Weapon/LMWeaponDataStructure.h"

View File

@ -3,7 +3,7 @@
#include "Weapon/LMWeaponManager.h"
#include "Weapon/LMWeapon.h"
#include "Weapon/LMWeaponBase.h"
ULMWeaponManager::ULMWeaponManager()
@ -14,21 +14,70 @@ ULMWeaponManager::ULMWeaponManager()
void ULMWeaponManager::BeginPlay()
{
Super::BeginPlay();
if (AmmoData.IsEmpty())
SetupAmmoData();
}
void ULMWeaponManager::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
if (AmmoDataTable)
SetupAmmoData();
}
void ULMWeaponManager::SetupAmmoData()
{
TArray<FLMAmmoData*> Rows;
AmmoData.Empty();
AmmoDataTable->GetAllRows(TEXT(""), Rows);
for (const auto Data : Rows)
{
if (AmmoData.Contains(Data->AmmoType))
continue;
AmmoData.Add(Data->AmmoType, *Data);
}
}
int ULMWeaponManager::RemoveAmmo(const EAmmoType Ammo, const int Count)
{
if (AmmoData.Contains(Ammo))
{
FLMAmmoData &Data = AmmoData[Ammo];
int Difference = Data.AmmoCount - Count;
UE_LOG(LogTemp, Display, TEXT("Difference: %i | Removing: %i | Storage: %i"), Difference, Count, Data.AmmoCount)
if (Difference < 0)
{
UE_LOG(LogTemp, Error, TEXT("%i - %i = %i"), Data.AmmoCount, Count, Data.AmmoCount - Count);
Data.AmmoCount = FMath::Clamp(Data.AmmoCount - Count, 0, Data.MaxAmmo);
UE_LOG(LogTemp, Warning, TEXT("Difference < 0 | Munition to add: %i | Removed: %i | New Munition: %i"), Count + Difference, Count, Data.AmmoCount)
return Count + Difference;
}
Data.AmmoCount -= Count;
UE_LOG(LogTemp, Warning, TEXT("New munition: %i | Removed: %i"), Data.AmmoCount, Count)
return Count;
}
return 0;
}
void ULMWeaponManager::Initialize(USkeletalMeshComponent* Mesh)
{
SetWeaponMeshComponent(Mesh);
for (auto Weapon : StartingWeapons)
{
if (Weapon)
{
ULMWeapon* Instance = NewObject<ULMWeapon>(this, Weapon);
Weapons.Add(Instance);
ArmsMesh = Mesh;
Instance->Initialize(Mesh->GetRelativeLocation());
}
for (auto WeaponTemplate : StartingWeapons)
{
if (!WeaponTemplate)
continue;
ALMWeaponBase* Instance = GetWorld()->SpawnActor<ALMWeaponBase>(WeaponTemplate);
Instance->Setup(ArmsMesh, GetOwner());
Weapons.Add(Instance);
}
if (!Weapons.IsEmpty())
@ -41,30 +90,45 @@ void ULMWeaponManager::AddAmmoType(EAmmoType AmmoType, int AmmoCount)
{
FString Debug = FString::Printf(TEXT("Adding %i ammo of type %i"), AmmoCount, AmmoType);
GEngine->AddOnScreenDebugMessage(1, 1.f, FColor::Cyan, Debug);
for (const auto Weapon : Weapons)
{
if (Weapon->WeaponDataStructure.AmmoType != AmmoType)
continue;
Weapon->AddAmmo(AmmoCount);
if (AmmoData.Contains(AmmoType))
{
AmmoData[AmmoType].AddAmmo(AmmoCount);
}
else
{
const FString Warning = FString::Printf(TEXT("Ammo type %i not found"), AmmoType);
GEngine->AddOnScreenDebugMessage(1, 2.f, FColor::Orange, Warning);
FLMAmmoData Data = FLMAmmoData();
Data.AmmoType = AmmoType;
Data.AmmoCount = AmmoCount;
AmmoData[AmmoType] = Data;
}
}
int ULMWeaponManager::GetAmmoCount(const EAmmoType AmmoType)
{
if (AmmoData.Contains(AmmoType))
return AmmoData[AmmoType].AmmoCount;
return 0;
}
void ULMWeaponManager::Fire()
{
ULMWeapon* Weapon = GetCurrentWeapon();
GEngine->AddOnScreenDebugMessage(2, 1.f, FColor::Cyan, "Fire");
Weapon->Fire();
ALMWeaponBase* Weapon = GetCurrentWeapon();
if (Weapon->State == EWeaponState::EWS_Idle)
Weapon->PrimaryFire();
}
void ULMWeaponManager::Reload()
{
GEngine->AddOnScreenDebugMessage(3, 1.f, FColor::Cyan, "Reloading");
ALMWeaponBase* Weapon = GetCurrentWeapon();
ULMWeapon* Weapon = GetCurrentWeapon();
Weapon->Reload();
if (Weapon->State == EWeaponState::EWS_Idle)
Weapon->Reload();
}
void ULMWeaponManager::SwitchWeapon(const int Direction)
@ -91,13 +155,10 @@ void ULMWeaponManager::SetWeapon(const int Index)
return;
}
GetCurrentWeapon()->SetActorHiddenInGame(true);
CurrentWeaponIndex = Index;
GetCurrentWeapon()->SetActorHiddenInGame(false);
if (WeaponMeshComponent)
{
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 5, FColor::Red, "Has Mesh");
WeaponMeshComponent->SetSkeletalMeshAsset(GetCurrentWeapon()->WeaponDataStructure.MeshWeapon);
}
GetCurrentWeapon()->OnEquip();
}

View File

@ -3,17 +3,12 @@
#pragma once
#include "CoreMinimal.h"
#include "LMAmmoType.h"
#include "GameFramework/Actor.h"
#include "LMAmmo.generated.h"
class USphereComponent;
UENUM(BlueprintType)
enum class EAmmoType : uint8
{
EAT_RadishAmmo UMETA(DisplayName = "Radish Ammo"),
EAT_CornAmmo UMETA(DisplayName = "Corn Ammo")
};
UCLASS()
class LEGUMEMIX_API ALMAmmo : public AActor

View File

@ -0,0 +1,30 @@
#pragma once
#include "LMAmmoType.h"
#include "Kismet/KismetMathLibrary.h"
#include "LMAmmoData.generated.h"
USTRUCT(BlueprintType)
struct FLMAmmoData : public FTableRowBase
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite)
EAmmoType AmmoType;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin=1, ClampMax=1000, Uimin=1, Uimax=1000))
int MaxAmmo = 32;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(ClampMin=0, Uimin=0))
int AmmoCount = 8;
/**
* An utility method to add and
* @param Quantity The quantity of ammo to add.
*/
void AddAmmo(const int Quantity)
{
AmmoCount += UKismetMathLibrary::Clamp(Quantity, 0, MaxAmmo);
}
};

View File

@ -0,0 +1,8 @@
#pragma once
UENUM(BlueprintType)
enum class EAmmoType : uint8
{
EAT_RadishAmmo UMETA(DisplayName = "Radish Ammo"),
EAT_CornAmmo UMETA(DisplayName = "Corn Ammo")
};

View File

@ -0,0 +1,4 @@
#pragma once
/** The Trace Channel for Bullets. */
#define TRACE_BULLET ECC_GameTraceChannel1

View File

@ -0,0 +1,41 @@
#pragma once
#include "Ammo/LMAmmoType.h"
#include "LMBulletInfo.generated.h"
USTRUCT(BlueprintType)
struct FLMBulletInfo
{
GENERATED_BODY()
/** The number of bullets to fire. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int BulletCount = 1;
/** The bullets' origins. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector Origin = FVector::ZeroVector;
/** The main direction vector. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FVector Direction = FVector::ForwardVector;
/** The Random bullet spread angle deviation. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Spread = 0.0f;
/** The maximum distance before the bullet reaches minimum damages. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float MaxDistance = 100000.f;
/** A curve multiplicating the damage of a bullet depending on the distance of the target. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UCurveFloat* Falloff = nullptr;
/** The type of bullet that was fired. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
EAmmoType AmmoType = EAmmoType::EAT_CornAmmo;
/** The default amount of damage to apply per bullet. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
float Damage = 10.f;
};

View File

@ -0,0 +1,103 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "LMHealthComponent.generated.h"
class ULMHitBox;
UCLASS(Blueprintable, ClassGroup=(Legumix), meta=(BlueprintSpawnableComponent))
class LEGUMEMIX_API ULMHealthComponent : public UActorComponent
{
GENERATED_BODY()
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnHealthChangedSignature, float, Health, float, Damage);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDeathSignature);
public:
ULMHealthComponent();
virtual void BeginPlay() override;
void Kill();
public:
/**
* Applies an amount of damage to the component.
* @param Damage The damage to apply the Health to.
*/
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category=Legumix)
void TakeDamage(float Damage);
/**
* Called automatically when the component hits zero health.
*/
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category=Legumix)
void OnKill();
/**
* Register all hitboxes associated with this component owner.
*/
UFUNCTION(BlueprintCallable, Category=Legumix, CallInEditor)
void RegisterHitBoxes();
/**
* Called automatically when a hitbox is hit.
* @param HitBox The hitbox that was hit.
* @param Damage The damage received by the hitbox.
*/
UFUNCTION()
void HitBoxHit(ULMHitBox* HitBox, float Damage);
/**
* Applies the amount of damage received to the component.
*
* Called automatically when one of this component's LMHitBox is hit.
* @param Damage The damage received.
*/
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category=Legumix)
void OnHit(float Damage);
/**
* Adds an amount of health to the character.
* @param AddedHealth The amount of health to add.
* @param NoLimits If sets, ignore the component's MaxHealth value.
*/
UFUNCTION(BlueprintCallable, Category=Legumix, meta=(Keywords = "Refill, Health"))
void AddHealth(const float AddedHealth, const bool NoLimits = false) { Health = FMath::Clamp(Health + AddedHealth, 0.0f, NoLimits ? INT_MAX : MaxHealth); }
/**
* Completely refill the health of the component.
*/
UFUNCTION(BlueprintCallable, Category=Legumix, meta=(Keywords = "Refill, Health"))
void FillHealth() { Health = MaxHealth; }
public:
/** Delegate called when this component receives damages. */
UPROPERTY(BlueprintAssignable, Category=Legumix)
FOnHealthChangedSignature OnHealthChanged;
/** Delegate called when this component is killed, aka. Health reaches 0.*/
UPROPERTY(BlueprintAssignable, Category=Legumix)
FOnDeathSignature OnDeath;
private:
/**
* If set, the Health will be initialized to MaxHealth.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
bool bMaxHealthOnStart = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true, ClampMin=0, UIMin=0))
float Health = 100.f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true, ClampMin=0, UIMin=0, UIMax=1000))
float MaxHealth = 100.f;
/**
* A list of all associated LMHitboxes.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
TArray<TObjectPtr<ULMHitBox>> HitBoxes;
};

View File

@ -0,0 +1,46 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "LMBulletInfo.h"
#include "Components/CapsuleComponent.h"
#include "LMHitBox.generated.h"
UCLASS(Blueprintable, ClassGroup=(Legumix), meta=(BlueprintSpawnableComponent))
class LEGUMEMIX_API ULMHitBox : public UCapsuleComponent
{
GENERATED_BODY()
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FHitBoxHitSignature, ULMHitBox*, HitBox, float, Damage);
public:
ULMHitBox();
void OnHit(const FLMBulletInfo& BulletInfo);
public:
UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category=Legumix)
float CalculateDamage(float Damage, float Distance, UCurveFloat* Falloff, float MaxDistance);
public:
/** Delegate called when the hitbox is hit.
* @param HitBox: The Hitbox that was hit.
* @param Damage: The amount of damage done to the hitbox.
*/
UPROPERTY(BlueprintAssignable, BlueprintCallable)
FHitBoxHitSignature OnHitBoxHit;
private:
/**
* A value to multiply the damage received by.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
float DamageModifier = 1.0f;
/**
* The Amount of damage removed when hit.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true, ClampMin=0.0f, UIMin=0.0f))
float FlatDamageAbsorption = 0.f;
};

View File

@ -3,6 +3,8 @@
#pragma once
#include "CoreMinimal.h"
#include "LMBulletInfo.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/Character.h"
#include "LMPlayer.generated.h"
@ -22,9 +24,26 @@ public:
virtual void Tick(float DeltaTime) override;
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UFUNCTION()
UFUNCTION(BlueprintCallable)
void PickUpAmmo(ALMAmmo* Ammo);
/**
* Gets the number of ammo from the given type.
* @param AmmoType The ammo type to get.
* @return The amount of ammo from the given type.
*/
UFUNCTION(BlueprintCallable)
int GetAmmoCount(EAmmoType AmmoType) const;
/**
* Removes a given amount of ammo from the type.
* @param AmmoType The type of ammo to remove.
* @param Count The amount of ammo to remove.
* @return The amount that was removed.
*/
UFUNCTION(BlueprintCallable)
int RemoveAmmo(EAmmoType AmmoType, int Count) const;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
@ -36,13 +55,28 @@ public:
UFUNCTION(BlueprintCallable)
void SetWeaponManager(ULMWeaponManager* Manager);
UFUNCTION(BlueprintCallable)
void PlayAnimation(UAnimMontage* Animation);
UFUNCTION(BlueprintCallable)
void FireBullets(const FLMBulletInfo Settings);
UFUNCTION(BlueprintCallable)
FVector GetWeaponFiringOrigin() const;
UFUNCTION(BlueprintCallable)
FVector GetAimVector() const;
private:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Legumix", meta = (AllowPrivateAccess = true))
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Legumix, meta = (AllowPrivateAccess = true))
TObjectPtr<ULMWeaponManager> WeaponManager;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Legumix", meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> WeaponSkeletalMeshComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta = (AllowPrivateAccess = true))
TObjectPtr<USkeletalMeshComponent> ArmsMesh;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Legumix", meta = (AllowPrivateAccess = true))
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta = (AllowPrivateAccess = true))
TObjectPtr<UCameraComponent> Camera;
private:
FRandomStream SpreadStream;
};

View File

@ -0,0 +1,17 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "LMWeaponBase.h"
#include "LMRevolver.generated.h"
UCLASS()
class LEGUMEMIX_API ALMRevolver : public ALMWeaponBase
{
GENERATED_BODY()
public:
ALMRevolver();
virtual void PrimaryFire() override;
};

View File

@ -0,0 +1,22 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "LMWeaponBase.h"
#include "LMShotgun.generated.h"
UCLASS()
class LEGUMEMIX_API ALMShotgun : public ALMWeaponBase
{
GENERATED_BODY()
public:
ALMShotgun();
virtual void PrimaryFire() override;
private:
/** The number of pellets fired by the shotgun. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta = (AllowPrivateAccess = true))
int PelletCount = 8;
};

View File

@ -0,0 +1,135 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Ammo/LMAmmo.h"
#include "LMWeaponState.h"
#include "GameFramework/Actor.h"
#include "LMWeaponBase.generated.h"
class ALMPlayer;
UCLASS()
class LEGUMEMIX_API ALMWeaponBase : public AActor
{
GENERATED_BODY()
public:
ALMWeaponBase();
virtual void BeginPlay() override;
void Setup(USkeletalMeshComponent* Mesh, AActor* CharOwner);
public:
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category=Legumix)
void OnEquip();
virtual void OnEquip_Implementation();
UFUNCTION(BlueprintCallable)
virtual bool Reload();
UFUNCTION(BlueprintCallable)
virtual void PrimaryFire();
UFUNCTION(BlueprintCallable)
void PlaySound(USoundWave* Sound, bool Replacing = false);
UFUNCTION(BlueprintCallable)
void PlayAnimation(UAnimMontage* Animation);
/** The socket to attach the weapon to.
* @return The socket.
*/
UFUNCTION(BlueprintCallable)
FName GetAttachmentSocketName() const { return WeaponSocket; }
UFUNCTION(BlueprintCallable, BlueprintImplementableEvent)
void OnDefaultReload();
protected:
UFUNCTION(BlueprintCallable)
void AllowRefire();
private:
bool DefaultReload();
public:
/** The current state of the weapon. */
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category="Legumix|Weapon")
EWeaponState State;
protected: /* Weapon Data */
FTimerHandle FireTimer;
FTimerHandle ReloadTimer;
/** The sound to play when firing. */
UPROPERTY(EditAnywhere, BlueprintReadWrite,Category="Legumix|Sounds")
TObjectPtr<USoundWave> FireSound;
UPROPERTY(EditAnywhere, BlueprintReadWrite,Category="Legumix|Sounds")
TObjectPtr<USoundWave> ReloadSound;
UPROPERTY(EditAnywhere, BlueprintReadWrite,Category="Legumix|Sounds")
TObjectPtr<USoundWave> DryFireSound;
UPROPERTY(EditAnywhere, BlueprintReadWrite,Category="Legumix|Sounds")
TObjectPtr<USoundWave> EquipSound;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Animations", meta=(AllowPrivateAccess=true))
TObjectPtr<UAnimMontage> PrimaryFireAnimation;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Legumix|Animations", meta=(AllowPrivateAccess=true))
TObjectPtr<UAnimMontage> ReloadAnimation;
/** The number of seconds before being able to fire again. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
float RefireDelay = 0.5f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
float ReloadDelay = 0.5f;
/** The flat damage number of one bullet. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
float Damage = 10.f;
/** The max angle deviation of a bullet from the original ray. In degrees.*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true, UIMin=0, UIMax=180))
float WeaponSpread = 10;
/** The max distance (cm) between the origin and the target before doing minimal damage. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
float MaxDistance = 100000.f;
/** The damage falloff distance in a 0-1 scale. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
TObjectPtr<UCurveFloat> DamageFalloff;
/** The type of ammo used by this weapon. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
EAmmoType AmmoType;
/** The current number of ammo in the clip. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
int ClipAmmo;
/** The maximum amount of ammo in a clip. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Weapon", meta=(AllowPrivateAccess=true))
int MaxClip;
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category=Legumix)
TObjectPtr<ALMPlayer> Player;
private:
/** An optional socket to attach the weapon to. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
FName WeaponSocket;
private: /* Components */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true))
TObjectPtr<UAudioComponent> AudioComponent;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true))
TObjectPtr<USkeletalMeshComponent> WeaponMesh;
};

View File

@ -1,6 +1,4 @@
#pragma once
#include "LMAmmo.h"
#include "LMWeaponDataStructure.generated.h"
USTRUCT(BlueprintType)
@ -8,18 +6,11 @@ struct FLMWeaponDataStructure : public FTableRowBase
{
GENERATED_BODY()
/** Max ammo in clip. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int MaxAmmo; // Max ammo in "inventory"
int MaxClipAmmo;
/** The animation blueprint to animate the mesh. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
int MaxClipAmmo; // Max ammo in clip
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<USkeletalMesh> MeshWeapon; //Mesh of the weapon display in the scene
UPROPERTY(EditAnywhere, BlueprintReadWrite)
EAmmoType AmmoType; //Type of ammo, which ammo this weapon is using
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UAnimBlueprint> AnimationBluePrint; //The animation blueprint to animate the mesh
TObjectPtr<UAnimBlueprint> AnimationBluePrint;
};

View File

@ -3,59 +3,77 @@
#pragma once
#include "CoreMinimal.h"
#include "LMAmmo.h"
#include "Ammo/LMAmmoData.h"
#include "Components/ActorComponent.h"
#include "LMWeaponManager.generated.h"
class ALMWeaponBase;
class ULMWeapon;
UCLASS(Blueprintable, BlueprintType, ClassGroup="Legumix", meta=(BlueprintSpawnableComponent))
UCLASS(Blueprintable, BlueprintType, ClassGroup=Legumix, meta=(BlueprintSpawnableComponent))
class LEGUMEMIX_API ULMWeaponManager : public UActorComponent
{
GENERATED_BODY()
public:
ULMWeaponManager();
void SetWeaponMeshComponent(USkeletalMeshComponent* Mesh) { WeaponMeshComponent = Mesh; }
void SetArmsMesh(USkeletalMeshComponent* Mesh) { ArmsMesh = Mesh; }
public:
/**
* Get the Weapon currently equipped.
* @return The Current Weapon.
*/
UFUNCTION(BlueprintCallable, Category="Legumix")
ULMWeapon* GetCurrentWeapon() { return Weapons[CurrentWeaponIndex]; }
UFUNCTION(BlueprintCallable, Category=Legumix)
ALMWeaponBase* GetCurrentWeapon() { return Weapons[CurrentWeaponIndex]; }
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void SetWeapon(int Index);
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void AddAmmoType(EAmmoType AmmoType, int AmmoCount);
UFUNCTION(BlueprintCallable, Category=Legumix)
int GetAmmoCount(EAmmoType AmmoType);
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void Fire();
UFUNCTION(BlueprintCallable, Category="Legumix")
UFUNCTION(BlueprintCallable, Category=Legumix)
void Reload();
void SwitchWeapon(int Direction);
void Initialize(USkeletalMeshComponent* Mesh);
UFUNCTION(BlueprintCallable, Category="Legumix|Ammo")
void SetupAmmoData();
UFUNCTION(BlueprintCallable, Category="Legumix|Ammo")
int RemoveAmmo(EAmmoType Ammo, int Count);
protected:
virtual void BeginPlay() override;
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix", meta = (AllowPrivateAccess = "true"))
TObjectPtr<USkeletalMeshComponent> WeaponMeshComponent;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta = (AllowPrivateAccess = "true"))
TObjectPtr<USkeletalMeshComponent> ArmsMesh;
private:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Ammo", meta=(AllowPrivateAccess=true))
TObjectPtr<UDataTable> AmmoDataTable;
/** The weapons the player starts with. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix", meta=(AllowPrivateAccess=true))
TArray<TSubclassOf<ULMWeapon>> StartingWeapons;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
TArray<TSubclassOf<ALMWeaponBase>> StartingWeapons;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Legumix", meta=(AllowPrivateAccess=true))
TArray<TObjectPtr<ULMWeapon>> Weapons;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Legumix, meta=(AllowPrivateAccess=true))
TArray<TObjectPtr<ALMWeaponBase>> Weapons;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix", meta=(AllowPrivateAccess=true))
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Legumix, meta=(AllowPrivateAccess=true))
int CurrentWeaponIndex = 0;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Legumix|Ammo", meta=(AllowPrivateAccess=true))
TMap<EAmmoType, FLMAmmoData> AmmoData;
};

View File

@ -0,0 +1,9 @@
#pragma once
UENUM(Blueprintable)
enum class EWeaponState : uint8
{
EWS_Idle = 0 UMETA(DisplayName = "Idle"),
EWS_Firing = 1 UMETA(DisplayName = "Firing"),
EWS_Reloading = 2 UMETA(DisplayName = "Reloading"),
};