diff --git a/Content/Characters/Mannequins/Meshes/SK_Mannequin.uasset b/Content/Characters/Mannequins/Meshes/SK_Mannequin.uasset new file mode 100644 index 0000000..d19866b Binary files /dev/null and b/Content/Characters/Mannequins/Meshes/SK_Mannequin.uasset differ diff --git a/Content/ProofOfConcept/ProjectileBase_BP.uasset b/Content/ProofOfConcept/ProjectileBase_BP.uasset new file mode 100644 index 0000000..0aa2f03 Binary files /dev/null and b/Content/ProofOfConcept/ProjectileBase_BP.uasset differ diff --git a/Source/OpenConflict/PlayerCharacter/DDICharacter.cpp b/Source/OpenConflict/PlayerCharacter/DDICharacter.cpp index 9238158..d3bda86 100644 --- a/Source/OpenConflict/PlayerCharacter/DDICharacter.cpp +++ b/Source/OpenConflict/PlayerCharacter/DDICharacter.cpp @@ -65,22 +65,26 @@ bool ADDICharacter::Server_SpawnProjectile_Validate() void ADDICharacter::Server_SpawnProjectile_Implementation() { FVector Location = GetActorLocation(); - FRotator Rotation = GetActorRotation(); + if (GetMesh()->DoesSocketExist("headSocket")) + Location = GetMesh()->GetSocketLocation("headSocket"); //Socket_Projectile + FRotator Rotation = GetViewRotation(); FVector Dir = GetActorForwardVector(); - // GetActorEyesViewPoint(Location, Rotation); + GetActorEyesViewPoint(Location, Rotation); - Location += Dir * 55.f; + Location += Dir * 155.f; if (!ProjectileClass) { - GEngine->AddOnScreenDebugMessage(1, 10.f, FColor::Emerald, "No Projectile Set"); + GEngine->AddOnScreenDebugMessage(2, 10.f, FColor::Emerald, "No Projectile Set"); return; } FActorSpawnParameters SpawnInfo; SpawnInfo.Owner = this; SpawnInfo.Instigator = GetInstigator(); + + GEngine->AddOnScreenDebugMessage(-1,10.f,FColor::Red,FString::Printf(TEXT("Server Spawning Projectile Location %f,%f,%f"), Location.X, Location.Y, Location.Z)); GetWorld()->SpawnActor(ProjectileClass, Location, Rotation, SpawnInfo); } diff --git a/Source/OpenConflict/PlayerCharacter/DDICharacter.cpp~ b/Source/OpenConflict/PlayerCharacter/DDICharacter.cpp~ new file mode 100644 index 0000000..d3bda86 --- /dev/null +++ b/Source/OpenConflict/PlayerCharacter/DDICharacter.cpp~ @@ -0,0 +1,124 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "DDICharacter.h" + +#include "Components/CapsuleComponent.h" +#include "GameFramework/SpringArmComponent.h" +#include "OpenConflict/Weapons/Projectiles/ProjectileBase.h" + +// Sets default values +ADDICharacter::ADDICharacter() +{ + // Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it. + PrimaryActorTick.bCanEverTick = true; + bReplicates = true; + // bReplicateMovement = true; + + CameraComponent = CreateDefaultSubobject(TEXT("CameraComponent")); + CameraComponent->SetupAttachment(GetMesh(), "headSocket"); + CameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f)); + CameraComponent->bUsePawnControlRotation = true; + + HealthComponent = CreateDefaultSubobject(TEXT("HealthComponent")); + + GetCapsuleComponent()->SetCollisionProfileName(TEXT("BlockAllDynamic")); + GetCapsuleComponent()->SetGenerateOverlapEvents(true); + GetCapsuleComponent()->SetNotifyRigidBodyCollision(true); + + +} + +// Called when the game starts or when spawned +void ADDICharacter::BeginPlay() +{ + Super::BeginPlay(); + + if (GetCapsuleComponent()) + { + GetCapsuleComponent()->OnComponentHit.AddDynamic(this, &ADDICharacter::OnHit); + } + +} + +// Called every frame +void ADDICharacter::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); + +} + +void ADDICharacter::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) +{ + Server_CharacterHit(HitComponent, OtherActor, OtherComp, NormalImpulse, Hit); +} + +void ADDICharacter::TakeDamage(int Damage) +{ + HealthComponent->TakeDamage(Damage); +} + +bool ADDICharacter::Server_SpawnProjectile_Validate() +{ + return true; +} +void ADDICharacter::Server_SpawnProjectile_Implementation() +{ + FVector Location = GetActorLocation(); + if (GetMesh()->DoesSocketExist("headSocket")) + Location = GetMesh()->GetSocketLocation("headSocket"); //Socket_Projectile + FRotator Rotation = GetViewRotation(); + FVector Dir = GetActorForwardVector(); + + GetActorEyesViewPoint(Location, Rotation); + + Location += Dir * 155.f; + + if (!ProjectileClass) + { + GEngine->AddOnScreenDebugMessage(2, 10.f, FColor::Emerald, "No Projectile Set"); + return; + } + + FActorSpawnParameters SpawnInfo; + SpawnInfo.Owner = this; + SpawnInfo.Instigator = GetInstigator(); + + GEngine->AddOnScreenDebugMessage(-1,10.f,FColor::Red,FString::Printf(TEXT("Server Spawning Projectile Location %f,%f,%f"), Location.X, Location.Y, Location.Z)); + GetWorld()->SpawnActor(ProjectileClass, Location, Rotation, SpawnInfo); +} + +void ADDICharacter::Client_CharacterHit_Implementation() +{ + TakeDamage(10); + OnDamageTaken(); + +} +bool ADDICharacter::Client_CharacterHit_Validate() +{ + return true; +} +void ADDICharacter::Server_CharacterHit_Implementation(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) +{ + if (AProjectileBase* Projectile = Cast(OtherActor)) + { + // if (Cast(Projectile->Owner) == this) + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Emerald, "Damage dealt"); + Client_CharacterHit(); + } +} +bool ADDICharacter::Server_CharacterHit_Validate(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) +{ + return true; +} + +void ADDICharacter::OnRep_Health() +{ + GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "Health Replicated"); +} + +void ADDICharacter::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const +{ + Super::GetLifetimeReplicatedProps(OutLifetimeProps); + DOREPLIFETIME(ADDICharacter, HealthComponent); +} \ No newline at end of file diff --git a/Source/OpenConflict/Weapons/Projectiles/ProjectileBase.cpp b/Source/OpenConflict/Weapons/Projectiles/ProjectileBase.cpp index e794add..88a1b71 100644 --- a/Source/OpenConflict/Weapons/Projectiles/ProjectileBase.cpp +++ b/Source/OpenConflict/Weapons/Projectiles/ProjectileBase.cpp @@ -33,13 +33,14 @@ void AProjectileBase::BeginPlay() if (collision) collision->OnComponentHit.AddDynamic(this, &AProjectileBase::OnHit); - } // Called every frame void AProjectileBase::Tick(float DeltaTime) { Super::Tick(DeltaTime); + FVector Location = GetActorLocation(); + GEngine->AddOnScreenDebugMessage(3,10.f,FColor::Red,FString::Printf(TEXT("Projectile Location %f,%f,%f"), Location.X, Location.Y, Location.Z)); } diff --git a/Source/OpenConflict/Weapons/WeaponBase.cpp b/Source/OpenConflict/Weapons/WeaponBase.cpp index 3df1ecd..bac4bc2 100644 --- a/Source/OpenConflict/Weapons/WeaponBase.cpp +++ b/Source/OpenConflict/Weapons/WeaponBase.cpp @@ -13,6 +13,7 @@ AWeaponBase::AWeaponBase() } + // Called when the game starts or when spawned void AWeaponBase::BeginPlay() { @@ -46,3 +47,82 @@ void AWeaponBase::MagRepacking() // } } } + +void AWeaponBase::Server_SpawnProjectile_Implementation() +{ + FVector Location; + if (WeaponMesh->DoesSocketExist("Socket_Projectile")) + Location = WeaponMesh->GetSocketLocation("Socket_Projectile"); + FRotator Rotation = GetActorRotation(); + FVector Dir = GetOwner()->GetActorForwardVector(); + + // GetActorEyesViewPoint(Location, Rotation); + if (Location.Equals(FVector::ZeroVector)) + Location += Dir * 55.f; + else + { + GEngine->AddOnScreenDebugMessage(2,10.f,FColor::Green,TEXT("Server Failed to get Socket Location")); + return; + } + + if (!ProjectileClass) + { + GEngine->AddOnScreenDebugMessage(2, 10.f, FColor::Emerald, "Server No Projectile Set"); + return; + } + + FActorSpawnParameters SpawnInfo; + SpawnInfo.Owner = GetOwner(); + SpawnInfo.Instigator = GetInstigator(); + SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + + GEngine->AddOnScreenDebugMessage(2,10.f,FColor::Red,FString::Printf(TEXT("Server Spawning Projectile Location %f,%f,%f"), Location.X, Location.Y, Location.Z)); + AActor* projectile = GetWorld()->SpawnActor(ProjectileClass, Location, Rotation, SpawnInfo); + + if (!projectile) + GEngine->AddOnScreenDebugMessage(2,10.f,FColor::Red,TEXT("Failed to Spawn")); + + Client_SpawnProjectile(); +} + +bool AWeaponBase::Server_SpawnProjectile_Validate() +{ + return true; +} + +void AWeaponBase::Client_SpawnProjectile_Implementation() +{ + FVector Location; + if (WeaponMesh->DoesSocketExist("Socket_Projectile")) + Location = WeaponMesh->GetSocketLocation("Socket_Projectile"); + FRotator Rotation = GetActorRotation(); + FVector Dir = GetActorForwardVector(); + + // GetActorEyesViewPoint(Location, Rotation); + if (Location.Equals(FVector::ZeroVector)) + Location += Dir * 55.f; + else + { + GEngine->AddOnScreenDebugMessage(1,10.f,FColor::Green,TEXT("Client Failed to get Socket Location")); + return; + } + + if (!ProjectileClass) + { + GEngine->AddOnScreenDebugMessage(1, 10.f, FColor::Emerald, "Client No Projectile Set"); + return; + } + + FActorSpawnParameters SpawnInfo; + SpawnInfo.Owner = this; + SpawnInfo.Instigator = GetInstigator(); + SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + + GEngine->AddOnScreenDebugMessage(1,10.f,FColor::Red,FString::Printf(TEXT("Client Spawning Projectile Location %f,%f,%f"), Location.X, Location.Y, Location.Z)); + GetWorld()->SpawnActor(ProjectileClass, Location, Rotation, SpawnInfo); +} + +bool AWeaponBase::Client_SpawnProjectile_Validate() +{ + return true; +} \ No newline at end of file diff --git a/Source/OpenConflict/Weapons/WeaponBase.h b/Source/OpenConflict/Weapons/WeaponBase.h index f65d3f3..964b223 100644 --- a/Source/OpenConflict/Weapons/WeaponBase.h +++ b/Source/OpenConflict/Weapons/WeaponBase.h @@ -37,6 +37,9 @@ private: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Weapon Ammo", meta=(AllowPrivateAccess=true)) int RESERVE_AMMO_POOL_DEFAULT = 120; + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon Ammo", meta=(AllowPrivateAccess=true)) + TSubclassOf ProjectileClass; + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta=(AllowPrivateAccess=true)) USkeletalMeshComponent* WeaponMesh; @@ -55,6 +58,13 @@ public: /*Functions*/ UFUNCTION() void MagRepacking(); + + + UFUNCTION(Server, Reliable, WithValidation, BlueprintCallable) + void Server_SpawnProjectile(); + + UFUNCTION(Client, Reliable, WithValidation, BlueprintCallable) + void Client_SpawnProjectile(); /*C++ only declarations*/ private: