Download

Help with FPS Bomb configuration

Greetings,

I purchased a FPS C++ template and I am in need of help, Im sure it is quite a simple task for a programmer, which I am not.

The issue Im having is the bomb is able to be planted with left-mouse-click, and this lets the bomb get planted anywhere within the level.
I do not want this to happen as I have static locations within the level that I want use.

The game has an interact interface that Im using and if I go to the static location in the level and press the use key it plants the bomb just as I want.
Only thing I wish to do is either disable the mouse-click to plant the bomb or change it to where only the use key can plant the bomb.

Here is my code:
Bomb.cpp


#include "FPSTemplate.h"
#include "Bomb.h"
#include "UnrealNetwork.h"
#include "Game/BombDefuse.h"
#include "Bomb/BombAreaVolume.h"
#include "Damage/DamageType_Explosion.h"
#include "BombSpot.h"

#define TimeToExplode 30.f

ABomb::ABomb(const FObjectInitializer & ObjectInitializer)
	: Super(ObjectInitializer)
{
	ExplosionDamage = 1000.f;
	ExplosionRadius = 1500.f;

	ItemSlot = EItemSlotEnum::Primary;
	Tags.Add(NAME_HideItem);
}

void ABomb::GetLifetimeReplicatedProps(TArray<FLifetimeProperty> & OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);

	DOREPLIFETIME(ABomb, ArmedContext);
}

bool ABomb::CanBePickedUp() const
{
	// Bomb can only be picked up when not planted
	return Super::CanBePickedUp() && !IsArmed();
}

void ABomb::AttachToBombSpot(class ABombSpot * BombSpot)
{
	Mesh->SetSimulatePhysics(false);
	AttachToComponent(BombSpot->BombSocket, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
}

void ABomb::ArmBomb(ABombSpot * BombSpot)
{
	GetWorldTimerManager().SetTimer(TimerHandle_Explode, this, &ABomb::Explode, TimeToExplode);

	ASoldier * Soldier = GetOwningSoldier();
	if (Soldier)
	{
		// Bomb is armed, drop it
		Soldier->DropItem();
	}

	if (BombSpot)
	{
		ArmedContext = BombSpot;
		AttachToBombSpot(BombSpot);
	}
	else
	{
		ArmedContext = this;
	}

	ABombDefuse * GameMode = Cast<ABombDefuse>(GetWorld()->GetAuthGameMode());
	if (GameMode)
	{
		// Notif game mode that bomb was armed
		GameMode->OnBombArmed();
	}
}

void ABomb::Explode()
{
	const FVector BombLocation = GetActorLocation();

	ABombDefuse * GameMode = Cast<ABombDefuse>(GetWorld()->GetAuthGameMode());
	if (GameMode)
	{
		// Check if bomb exploded in bomb area
		bool bInBombArea;
		if (ArmedContext && ArmedContext->IsA<ABombSpot>())
		{
			bInBombArea = true;
		}
		else
		{
			bInBombArea = false;

			for (TActorIterator<ABombAreaVolume> VolumeItr(GetWorld()); VolumeItr; ++VolumeItr)
			{
				if (VolumeItr->GetBrushComponent()->OverlapComponent(BombLocation, FQuat::Identity, FCollisionShape::MakeSphere(20.f)))//VolumeItr->IsOverlappingActor(this))
				{
					bInBombArea = true;
					break;
				}
			}
		}

		// Terrorists only win when bomb exploded in the bomb area
		if (bInBombArea)
		{
			GameMode->EndRound(ETeamEnum::TeamB);
		}
		else
		{
			GameMode->EndRound(ETeamEnum::TeamA);
		}
	}

	UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ExplosionEmitter, BombLocation);
	UGameplayStatics::SpawnSoundAtLocation(GetWorld(), ExplosionCue, BombLocation);

	TArray<AActor *> ActorsToIgnore;
	ActorsToIgnore.Add(this);
	UGameplayStatics::ApplyRadialDamageWithFalloff(this, ExplosionDamage, 0.f, BombLocation, 0.f, ExplosionRadius, 1.f, UDamageType_Explosion::StaticClass(), ActorsToIgnore);

	Destroy();
}

float ABomb::GetRemainingTime() const
{
	return GetWorldTimerManager().GetTimerRemaining(TimerHandle_Explode);
}

void ABomb::StartFiring()
{
	ABombDefuse * GameMode = Cast<ABombDefuse>(GetWorld()->GetAuthGameMode());
	if (GameMode && GameMode->HasRoundStarted())
	{
		if (PerformTask(EItemTaskEnum::Fire, ArmAnimation.Length))
		{
			OnFire();
		}
	}
}

void ABomb::OnFired()
{
	ArmBomb(NULL);
}

void ABomb::OnFire()
{
	PlayAnimation(ArmAnimation);
}

bool ABomb::CanSoldierInteract(ASoldier * Soldier) const
{
	// Soldiers can only interact if they are not in terrorist team and the bomb is actually planted
	return IsArmed() && Soldier->GetTeam() == ETeamEnum::TeamA;
}

float ABomb::GetInteractionLength() const
{
	return 4.f;
}

FVector ABomb::GetInteractionLocation() const
{
	return GetActorLocation();
}

void ABomb::OnInteract(ASoldier * Soldier)
{
	ArmedContext = NULL;
	GetWorldTimerManager().ClearTimer(TimerHandle_Explode);

	ABombDefuse * GameMode = Cast<ABombDefuse>(GetWorld()->GetAuthGameMode());
	if (GameMode)
	{
		// Bomb defused, terrorists lose
		GameMode->EndRound(ETeamEnum::TeamA);
	}
}

void ABomb::OnRep_ArmedContext()
{
	if (ArmedContext)
	{
		if (ArmedContext->IsA<ABombSpot>())
		{
			ABombSpot * BombSpot = Cast<ABombSpot>(ArmedContext);
			AttachToBombSpot(BombSpot);
		}

		GetWorldTimerManager().SetTimer(TimerHandle_Explode, TimeToExplode, false);
	}
	else
	{
		GetWorldTimerManager().ClearTimer(TimerHandle_Explode);
	}
}

and Bomb.h


#pragma once

#include "Soldier/Soldier.h"
#include "Items/Item.h"
#include "Bomb.generated.h"

// Class for a bomb in BombDefuse game mode
UCLASS()
class FPSTEMPLATE_API ABomb : public AItem
{
	GENERATED_BODY()

	FTimerHandle TimerHandle_Explode;

	// Context actor for an armed bomb, can the this if the bomb is planted on the ground or point to a bomb spot
	UPROPERTY(ReplicatedUsing = OnRep_ArmedContext)
		AActor * ArmedContext;

	UFUNCTION()
		void OnRep_ArmedContext();

public:
	// Animation for arming the bomb
	UPROPERTY(EditDefaultsOnly, Category = Animations)
		FItemAnimation ArmAnimation;

	UPROPERTY(EditDefaultsOnly, Category = Bomb)
		UParticleSystem * ExplosionEmitter;

	UPROPERTY(EditDefaultsOnly, Category = Bomb)
		USoundCue * ExplosionCue;

	UPROPERTY(EditDefaultsOnly, Category = Bomb)
		float ExplosionDamage;

	UPROPERTY(EditDefaultsOnly, Category = Bomb)
		float ExplosionRadius;

	ABomb(const FObjectInitializer & ObjectInitializer);

	virtual bool CanBePickedUp() const override;

	UFUNCTION(BlueprintPure, Category = Bomb)
		bool IsArmed() const { return ArmedContext != NULL; }

	void AttachToBombSpot(class ABombSpot * BombSpot);

	// Setup timer and everything
	void ArmBomb(class ABombSpot * BombSpot);

	// Explode this bomb, i.e. apply damage and end the round
	void Explode();

	// Returns remaining time to explosion
	UFUNCTION(BlueprintPure, Category = Bomb)
		float GetRemainingTime() const;

	virtual void StartFiring() override;

	virtual void OnFired() override;

	virtual void OnFire() override;

	// Interaction interface used for defusing
	virtual bool CanSoldierInteract(ASoldier * Soldier) const override;
	
	virtual float GetInteractionLength() const override;

	virtual FVector GetInteractionLocation() const override;

	virtual void OnInteract(ASoldier * Soldier) override;
	
};


Thank you in advance for any help and time offered to my problem !

Well what I would do is make a new volume. BP or Code, its up to you, and in the ArmBomb(ABombSpot * BombSpot) make a check if the player is in the voule. If he is then allow them to plant, if not, then dont allow them. Maybe playing around with the volume and it’s overlay properties should do the trick. Hope that’s help ypu in any way