159 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
// Fill out your copyright notice in the Description page of Project Settings.
 | 
						|
 | 
						|
 | 
						|
#include "BasePawn.h"
 | 
						|
#include "Components/StaticMeshComponent.h"
 | 
						|
#include "GameFramework/FloatingPawnMovement.h"
 | 
						|
#include "Util.h"
 | 
						|
 | 
						|
#define LogInfo(Msg) Util::log_info(TEXT("ABasePawn"), Msg)
 | 
						|
 | 
						|
// Sets default values
 | 
						|
ABasePawn::ABasePawn(const FObjectInitializer &object_initializer): 
 | 
						|
	APawn(object_initializer)
 | 
						|
{
 | 
						|
	// Create default components.
 | 
						|
	root_component = object_initializer.CreateDefaultSubobject<USceneComponent>(this, FName("Root"));
 | 
						|
	RootComponent = root_component;
 | 
						|
 | 
						|
	collision = object_initializer.CreateDefaultSubobject<UBoxComponent>(this, FName("Collision"));
 | 
						|
	collision->SetupAttachment(RootComponent);
 | 
						|
	collision->SetCollisionProfileName(FName("Pawn"));
 | 
						|
	collision->SetCanEverAffectNavigation(false);
 | 
						|
 | 
						|
	player_mesh = object_initializer.CreateDefaultSubobject<UStaticMeshComponent>(this, FName("PlayerMesh"));
 | 
						|
	player_mesh->SetupAttachment(collision);
 | 
						|
	player_mesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);
 | 
						|
	player_mesh->SetCanEverAffectNavigation(false);
 | 
						|
 | 
						|
	movement_component = object_initializer.CreateDefaultSubobject<UFloatingPawnMovement>(this, FName("MovementComponent"));
 | 
						|
	movement_component->UpdatedComponent = collision;
 | 
						|
 | 
						|
 | 
						|
	PrimaryActorTick.bCanEverTick = true;
 | 
						|
 | 
						|
	// Set defaults.
 | 
						|
	max_health = 100;
 | 
						|
}
 | 
						|
 | 
						|
// Called when the game starts or when spawned
 | 
						|
void ABasePawn::BeginPlay()
 | 
						|
{
 | 
						|
	Super::BeginPlay();
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Setup collision handler.
 | 
						|
	 */
 | 
						|
	collision->OnComponentHit.AddDynamic(this, &ABasePawn::handle_hit);
 | 
						|
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Set base state.
 | 
						|
	 */
 | 
						|
	current_health = max_health;
 | 
						|
}
 | 
						|
 | 
						|
void ABasePawn::handle_hit(
 | 
						|
	UPrimitiveComponent* hit_component,
 | 
						|
	AActor* other_actor,
 | 
						|
	UPrimitiveComponent* other_component,
 | 
						|
	FVector normal_impulse,
 | 
						|
	const FHitResult& hit
 | 
						|
)
 | 
						|
{
 | 
						|
	UClass* other_class = other_actor->GetClass();
 | 
						|
	if (damage_class_map.Contains(other_class))
 | 
						|
	{
 | 
						|
		// Update current health.
 | 
						|
		current_health -= damage_class_map[other_class];
 | 
						|
		LogInfo(FString::Printf(TEXT("Total health %d"), current_health));
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
UPawnMovementComponent* ABasePawn::GetMovementComponent() const
 | 
						|
{
 | 
						|
	return movement_component;
 | 
						|
}
 | 
						|
 | 
						|
FVector ABasePawn::get_location() const
 | 
						|
{
 | 
						|
	return collision->GetComponentLocation();
 | 
						|
}
 | 
						|
 | 
						|
// Called every frame
 | 
						|
void ABasePawn::Tick(float DeltaTime)
 | 
						|
{
 | 
						|
	Super::Tick(DeltaTime);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Handle death.
 | 
						|
	 */
 | 
						|
	if (current_health <= 0)
 | 
						|
	{
 | 
						|
		handle_death();
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void ABasePawn::handle_move_forward(float axis)
 | 
						|
{
 | 
						|
	FRotator rotation = Controller->GetControlRotation();
 | 
						|
	FRotator yaw(0.0f, rotation.Yaw, 0.0f);
 | 
						|
 | 
						|
	FVector forward = FRotationMatrix(yaw).GetUnitAxis(EAxis::X);
 | 
						|
	AddMovementInput(forward, axis);
 | 
						|
}
 | 
						|
 | 
						|
void ABasePawn::handle_move_right(float axis)
 | 
						|
{
 | 
						|
	FRotator rotation = Controller->GetControlRotation();
 | 
						|
	FRotator yaw(0.0f, rotation.Yaw, 0.0f);
 | 
						|
 | 
						|
	FVector right = FRotationMatrix(yaw).GetUnitAxis(EAxis::Y);
 | 
						|
	AddMovementInput(right, axis);
 | 
						|
}
 | 
						|
 | 
						|
void ABasePawn::shoot()
 | 
						|
{
 | 
						|
	FVector player_location = player_mesh->GetComponentLocation();
 | 
						|
	FRotator rotation = Controller->GetControlRotation();
 | 
						|
	FRotator yaw(0.0f, rotation.Yaw, 0.0f);
 | 
						|
	FVector forward = FRotationMatrix(yaw).GetUnitAxis(EAxis::X) * 100;
 | 
						|
 | 
						|
	FVector spawn_location = player_location + forward;
 | 
						|
	FActorSpawnParameters spawnParameters;
 | 
						|
	spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
 | 
						|
	spawnParameters.Owner = this;
 | 
						|
	spawnParameters.Instigator = this;
 | 
						|
	AActor* bullet = GetWorld()->SpawnActor<AActor>(
 | 
						|
		bullet_actor_class,
 | 
						|
		spawn_location,
 | 
						|
		FRotator(0,0,0),
 | 
						|
		spawnParameters
 | 
						|
	);
 | 
						|
}
 | 
						|
 | 
						|
void ABasePawn::handle_death()
 | 
						|
{
 | 
						|
	/*
 | 
						|
	 * Disable collision.
 | 
						|
	 */
 | 
						|
	collision->SetCollisionEnabled(ECollisionEnabled::NoCollision);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Spawn particle effect.
 | 
						|
	 */
 | 
						|
	FVector player_location = player_mesh->GetComponentLocation();
 | 
						|
	FActorSpawnParameters spawnParameters;
 | 
						|
	spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
 | 
						|
	AActor* bullet = GetWorld()->SpawnActor<AActor>(
 | 
						|
		death_class,
 | 
						|
		player_location,
 | 
						|
		FRotator(0,0,0),
 | 
						|
		spawnParameters
 | 
						|
	);
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Remove thyself from this world.
 | 
						|
	 */
 | 
						|
	Destroy();
 | 
						|
} |