Skip to content
This repository was archived by the owner on Jul 27, 2026. It is now read-only.

Commit 15c352b

Browse files
committed
Added source code for the game
0 parents  commit 15c352b

47 files changed

Lines changed: 3150 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Private/Bush.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "Bush.h"
2+
3+
/**
4+
* @brief Constructor
5+
* @details Sets up the audio component, static mesh, and scene root. Binds the OnOverlapBegin function to the OnComponentBeginOverlap event of the static mesh
6+
*/
7+
ABush::ABush()
8+
{
9+
Audio = CreateDefaultSubobject<UAudioComponent>(TEXT("Audio"));
10+
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("StaticMesh"));
11+
SphereCollider = CreateDefaultSubobject<USphereComponent>(TEXT("SphereCollider"));
12+
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
13+
14+
SetRootComponent(SceneRoot); // Set the scene root as the root component
15+
StaticMesh->SetupAttachment(SceneRoot); // Attach the static mesh to the scene root
16+
Audio->SetupAttachment(StaticMesh); // Attach the audio component to the static mesh
17+
SphereCollider->SetupAttachment(StaticMesh); // Attach the sphere collider to the static mesh
18+
19+
//StaticMesh->SetCollisionProfileName("OverlapAll"); // Set the collision profile of the static mesh to overlap all
20+
21+
SphereCollider->OnComponentBeginOverlap.AddDynamic(this, &ABush::OnOverlapBegin); // Bind the OnOverlapBegin function to the OnComponentBeginOverlap event of the static mesh
22+
23+
Audio->bAutoActivate = false; // Don't play the audio component on begin play
24+
}
25+
26+
/**
27+
* @brief Function that is called when the game starts or when spawned
28+
* @details Stops the audio component from playing on begin play
29+
*/
30+
void ABush::BeginPlay()
31+
{
32+
Super::BeginPlay();
33+
34+
Audio->Stop(); // Stop the audio component from playing on begin play
35+
}
36+
37+
/**
38+
* @brief Function that is called when the actor is being overlapped by another actor
39+
* @details Plays the sound if it exists and is not already playing
40+
*
41+
* @param OverlappedComponent The component that is being overlapped
42+
* @param OtherActor The actor that is overlapping
43+
* @param OtherComp The component of the actor that is overlapping
44+
* @param OtherBodyIndex The body index of the actor that is overlapping
45+
* @param bFromSweep Whether the overlap was from a sweep
46+
* @param SweepResult The result of the sweep
47+
*/
48+
void ABush::OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
49+
{
50+
// if (Audio->Sound && !Audio->IsPlaying()) Audio->Play(); // Don't interrupt the sound if it is already playing
51+
52+
if (Audio->Sound)
53+
{
54+
if (Audio->IsPlaying()) Audio->Stop(); // Interrupt the sound if it is already playing
55+
56+
Audio->Play();
57+
}
58+
}

Private/Chest.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
#include "Chest.h"
3+
4+
/**
5+
* @brief Construct a new AChest::AChest object
6+
* @details Set the collectable flag to false and the unique interaction flag to true
7+
*/
8+
AChest::AChest()
9+
{
10+
bCollectable = false; // Chests are not collectable
11+
bUniqueInteraction = true; // Chests can only be opened with once
12+
13+
ChestTop = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ChestTop")); // Create the chest top
14+
ChestTop->SetupAttachment(StaticMesh); // Attach the chest top to the static mesh
15+
16+
Loot = TArray<AActor*>(); // Initialize the loot array
17+
}
18+
19+
/**
20+
* @brief Called when the game starts or when spawned
21+
*/
22+
void AChest::BeginPlay()
23+
{
24+
Super::BeginPlay();
25+
26+
GetAttachedActors(Loot); // Get all attached actors and add them to the loot array
27+
28+
// Disable collision and hide the loot
29+
for (AActor* Item : Loot)
30+
{
31+
if (!Item) continue;
32+
Item->SetActorHiddenInGame(true);
33+
Item->SetActorEnableCollision(false);
34+
}
35+
}
36+
37+
/**
38+
* @brief Function to be called when the object is interacted with
39+
*/
40+
void AChest::Interact()
41+
{
42+
Super::Interact();
43+
44+
OpenChest(); // Open the chest
45+
}
46+
47+
/**
48+
* @brief Opens the chest
49+
* @details Rotates the chest top and shows the loot inside
50+
*/
51+
void AChest::OpenChest()
52+
{
53+
// Rotate the chest top 70 degrees (replaced with Timeline animation in the Blueprint version)
54+
// FRotator NewRotation = ChestTop->GetComponentRotation();
55+
// NewRotation.Roll += 70.0f;
56+
// ChestTop->SetWorldRotation(NewRotation);
57+
58+
// Enable collision and show the loot
59+
for (AActor* Item : Loot)
60+
{
61+
if (!Item) continue;
62+
Item->SetActorHiddenInGame(false);
63+
Item->SetActorEnableCollision(true);
64+
}
65+
}

Private/CombinationChest.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "CombinationChest.h"
2+
3+
#include "Kismet/GameplayStatics.h"
4+
5+
/**
6+
* @brief Constructor
7+
*/
8+
ACombinationChest::ACombinationChest()
9+
{
10+
// Set the combination code
11+
CombinationCode.SetNum(3);
12+
CombinationCode[0] = 3;
13+
CombinationCode[1] = 4;
14+
CombinationCode[2] = 6;
15+
}
16+
17+
/**
18+
* @brief Called when the game starts or when spawned
19+
*/
20+
void ACombinationChest::BeginPlay()
21+
{
22+
Super::BeginPlay();
23+
}
24+
25+
/**
26+
* @brief Function to be called when the object is interacted with
27+
*/
28+
void ACombinationChest::Interact()
29+
{
30+
if (OnInteracted.IsBound()) OnInteracted.Broadcast(this); // Broadcast the interaction event
31+
}
32+
33+
void ACombinationChest::CheckCode(TArray<int32> Code)
34+
{
35+
// Check if the code is correct
36+
if (Code[0] == CombinationCode[0] && Code[1] == CombinationCode[1] && Code[2] == CombinationCode[2])
37+
{
38+
if (OnInteracted.IsBound()) OnInteracted.Clear(); // Clear the interaction event binding so the UI does not show again
39+
OnCorrectCode.Broadcast(); // Broadcast the correct code event to play the animation
40+
Super::Interact(); // Call the parent interact function to open the chest and play the sound
41+
}
42+
else
43+
{
44+
// Play a sound to indicate the code is incorrect
45+
if (IncorrectCodeSound) UGameplayStatics::PlaySoundAtLocation(GetWorld(), IncorrectCodeSound, GetActorLocation());
46+
}
47+
}

Private/CombinationUI.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#include "CombinationUI.h"
2+
3+
#include "Kismet/GameplayStatics.h"
4+
5+
/**
6+
* @brief Called when the game starts or when spawned
7+
*/
8+
void UCombinationUI::NativeConstruct()
9+
{
10+
Super::NativeConstruct();
11+
12+
RootWidget->SetVisibility(ESlateVisibility::Hidden);
13+
14+
// Find the combination chest in the level and add a dynamic delegate to the OnInteracted event
15+
TArray<AActor*> CombinationChests = TArray<AActor*>();
16+
UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACombinationChest::StaticClass(), CombinationChests);
17+
18+
for (auto Actor : CombinationChests)
19+
{
20+
CombinationChest = Cast<ACombinationChest>(Actor);
21+
if (!CombinationChest) continue;
22+
CombinationChest->OnInteracted.AddDynamic(this, &UCombinationUI::ShowCombinationUI);
23+
}
24+
25+
// Add dynamic delegates to the increase and decrease buttons, as well as the submit button
26+
Number1Up->OnClicked.AddDynamic(this, &UCombinationUI::IncreaseNumber1);
27+
Number1Down->OnClicked.AddDynamic(this, &UCombinationUI::DecreaseNumber1);
28+
Number2Up->OnClicked.AddDynamic(this, &UCombinationUI::IncreaseNumber2);
29+
Number2Down->OnClicked.AddDynamic(this, &UCombinationUI::DecreaseNumber2);
30+
Number3Up->OnClicked.AddDynamic(this, &UCombinationUI::IncreaseNumber3);
31+
Number3Down->OnClicked.AddDynamic(this, &UCombinationUI::DecreaseNumber3);
32+
SubmitButton->OnClicked.AddDynamic(this, &UCombinationUI::SubmitCombination);
33+
34+
// Set the initial values of the numbers
35+
NumberValues.SetNum(3);
36+
NumberValues[0] = 0;
37+
NumberValues[1] = 0;
38+
NumberValues[2] = 0;
39+
40+
// Set the text of the numbers
41+
Number1->SetText(FText::FromString(FString::FromInt(NumberValues[0])));
42+
Number2->SetText(FText::FromString(FString::FromInt(NumberValues[1])));
43+
Number3->SetText(FText::FromString(FString::FromInt(NumberValues[2])));
44+
}
45+
46+
/**
47+
* @brief Function to show the combination UI
48+
*/
49+
void UCombinationUI::ShowCombinationUI(AActor* InteractedActor)
50+
{
51+
// Show the combination UI
52+
RootWidget->SetVisibility(ESlateVisibility::Visible);
53+
54+
// Set the focus to the first number
55+
Number1Up->SetKeyboardFocus();
56+
57+
// Show mouse cursor and set input mode to UI only
58+
if (APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0))
59+
{
60+
PlayerController->bShowMouseCursor = true;
61+
PlayerController->SetInputMode(FInputModeUIOnly());
62+
}
63+
}
64+
65+
/**
66+
* @brief Function to hide the combination UI
67+
*/
68+
void UCombinationUI::HideCombinationUI()
69+
{
70+
// Hide mouse cursor and set input mode to game only
71+
if (APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0))
72+
{
73+
PlayerController->bShowMouseCursor = false;
74+
PlayerController->SetInputMode(FInputModeGameOnly());
75+
}
76+
77+
// Hide the combination UI
78+
RootWidget->SetVisibility(ESlateVisibility::Hidden);
79+
}
80+
81+
/**
82+
* @brief Function to increase the first number
83+
* @details Increase the value of NumberValues[0] by 1 and update the text
84+
*/
85+
void UCombinationUI::IncreaseNumber1()
86+
{
87+
NumberValues[0] = (NumberValues[0] + 1) % 10;
88+
Number1->SetText(FText::FromString(FString::FromInt(NumberValues[0])));
89+
}
90+
91+
/**
92+
* @brief Function to decrease the first number
93+
* @details Decrease the value of NumberValues[0] by 1 and update the text
94+
*/
95+
void UCombinationUI::DecreaseNumber1()
96+
{
97+
NumberValues[0] = (NumberValues[0] - 1 + 10) % 10;
98+
Number1->SetText(FText::FromString(FString::FromInt(NumberValues[0])));
99+
}
100+
101+
/**
102+
* @brief Function to increase the second number
103+
* @details Increase the value of NumberValues[1] by 1 and update the text
104+
*/
105+
void UCombinationUI::IncreaseNumber2()
106+
{
107+
NumberValues[1] = (NumberValues[1] + 1) % 10;
108+
Number2->SetText(FText::FromString(FString::FromInt(NumberValues[1])));
109+
}
110+
111+
/**
112+
* @brief Function to decrease the second number
113+
* @details Decrease the value of NumberValues[1] by 1 and update the text
114+
*/
115+
void UCombinationUI::DecreaseNumber2()
116+
{
117+
NumberValues[1] = (NumberValues[1] - 1 + 10) % 10;
118+
Number2->SetText(FText::FromString(FString::FromInt(NumberValues[1])));
119+
}
120+
121+
/**
122+
* @brief Function to increase the third number
123+
* @details Increase the value of NumberValues[2] by 1 and update the text
124+
*/
125+
void UCombinationUI::IncreaseNumber3()
126+
{
127+
NumberValues[2] = (NumberValues[2] + 1) % 10;
128+
Number3->SetText(FText::FromString(FString::FromInt(NumberValues[2])));
129+
}
130+
131+
/**
132+
* @brief Function to decrease the third number
133+
* @details Decrease the value of NumberValues[2] by 1 and update the text
134+
*/
135+
void UCombinationUI::DecreaseNumber3()
136+
{
137+
NumberValues[2] = (NumberValues[2] - 1 + 10) % 10;
138+
Number3->SetText(FText::FromString(FString::FromInt(NumberValues[2])));
139+
}
140+
141+
/**
142+
* @brief Function to submit the combination
143+
* @details Check if the combination is correct and call the Interact function of the combination chest
144+
*/
145+
void UCombinationUI::SubmitCombination()
146+
{
147+
HideCombinationUI(); // Hide the combination UI
148+
CombinationChest->CheckCode(NumberValues); // Check the combination
149+
}

0 commit comments

Comments
 (0)