diff --git a/Content/Environment/Ball/BP_Ball.uasset b/Content/Environment/Ball/BP_Ball.uasset index 1061bfebd..1d6407ea7 100644 Binary files a/Content/Environment/Ball/BP_Ball.uasset and b/Content/Environment/Ball/BP_Ball.uasset differ diff --git a/Content/Game/BP_Cloud9Console.uasset b/Content/Game/BP_Cloud9Console.uasset index c19332d1b..d108a1898 100644 Binary files a/Content/Game/BP_Cloud9Console.uasset and b/Content/Game/BP_Cloud9Console.uasset differ diff --git a/Content/Maps/warmup.umap b/Content/Maps/warmup.umap index 00563cff6..cc6939408 100644 Binary files a/Content/Maps/warmup.umap and b/Content/Maps/warmup.umap differ diff --git a/Source/Cloud9/Character/Cloud9Character.cpp b/Source/Cloud9/Character/Cloud9Character.cpp index cc105cf83..fb8ac304c 100644 --- a/Source/Cloud9/Character/Cloud9Character.cpp +++ b/Source/Cloud9/Character/Cloud9Character.cpp @@ -55,7 +55,7 @@ const FName ACloud9Character::AnimationComponentName = TEXT("AnimationComponent" ACloud9Character::ACloud9Character(const FObjectInitializer& ObjectInitializer) : Super( ObjectInitializer.SetDefaultSubobjectClass(CharacterMovementComponentName)) { - constexpr float CharacterHeight = 72.0f; + constexpr float CharacterHeight = 144.0f; constexpr float CharacterRadius = 32.0f; constexpr float CharacterRotationYaw = -90.0f; constexpr float CharacterCameraBoomYaw = -60.0f; @@ -70,7 +70,7 @@ ACloud9Character::ACloud9Character(const FObjectInitializer& ObjectInitializer) DestroyAfterTime = 10.0f; let MyCapsuleComponent = GetCapsuleComponent(); - MyCapsuleComponent->InitCapsuleSize(CharacterRadius, CharacterHeight); + MyCapsuleComponent->InitCapsuleSize(CharacterRadius, CharacterHeight / 2.0f); MyCapsuleComponent->CanCharacterStepUpOn = CanStepUpOn; let Movement = GetCharacterMovement(); @@ -90,7 +90,7 @@ ACloud9Character::ACloud9Character(const FObjectInitializer& ObjectInitializer) TopDownCameraComponent->bUsePawnControlRotation = false; // Camera does not rotate relative to arm USkeletalMeshComponent* MyMesh = GetMesh(); - MyMesh->SetRelativeLocation({0.0f, 0.0f, -CharacterHeight}); + MyMesh->SetRelativeLocation({0.0f, 0.0f, -MyCapsuleComponent->GetScaledCapsuleHalfHeight()}); MyMesh->SetRelativeRotation({0.0f, CharacterRotationYaw, 0.0f}); // Create a decal in the world to show the cursor's location @@ -264,11 +264,7 @@ UCloud9InventoryComponent* ACloud9Character::GetInventoryComponent() const { ret UCloud9HealthComponent* ACloud9Character::GetHealthComponent() const { return HealthComponent; } -UCloud9AnimationComponent* ACloud9Character::GetAnimationComponent() const -{ - assertf(IsValid(AnimationComponent), "AnimationComponent isn't valid") - return AnimationComponent; -} +UCloud9AnimationComponent* ACloud9Character::GetAnimationComponent() const { return AnimationComponent; } void ACloud9Character::AddScore() { diff --git a/Source/Cloud9/Character/Components/Cloud9InventoryComponent.cpp b/Source/Cloud9/Character/Components/Cloud9InventoryComponent.cpp index 247af3c96..3612b5eb2 100644 --- a/Source/Cloud9/Character/Components/Cloud9InventoryComponent.cpp +++ b/Source/Cloud9/Character/Components/Cloud9InventoryComponent.cpp @@ -39,6 +39,15 @@ UCloud9InventoryComponent::UCloud9InventoryComponent() WeaponSlots.SetNum(SlotsNumber); } +void UCloud9InventoryComponent::OnUnregister() +{ + Super::OnUnregister(); + // TODO: Drop the most expensive weapon when owner died but for now just destroy all items + WeaponSlots + | ETContainer::Filter{[](let It) { return It != nullptr; }} + | ETContainer::ForEach{[](let It) { It->Destroy(); }}; +} + bool UCloud9InventoryComponent::Initialize(const TArray& WeaponConfigs, EWeaponSlot WeaponSlot) { WeaponConfigs diff --git a/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h b/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h index 8bce9a433..81aac4f35 100644 --- a/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h +++ b/Source/Cloud9/Character/Components/Cloud9InventoryComponent.h @@ -50,6 +50,8 @@ class CLOUD9_API UCloud9InventoryComponent : public UActorComponent public: UCloud9InventoryComponent(); + virtual void OnUnregister() override; + bool Initialize(const TArray& WeaponConfigs, EWeaponSlot WeaponSlot); /** diff --git a/Source/Cloud9/Contollers/Cloud9MouseController.cpp b/Source/Cloud9/Contollers/Cloud9MouseController.cpp index c29785fef..72e81ebc6 100644 --- a/Source/Cloud9/Contollers/Cloud9MouseController.cpp +++ b/Source/Cloud9/Contollers/Cloud9MouseController.cpp @@ -53,6 +53,8 @@ UCloud9MouseController::UCloud9MouseController() CameraRotationBase = FVector2D::ZeroVector; IsMouseRotationMode = false; + + bIsLastCrosshairLocationValid = false; } FVector2D UCloud9MouseController::GetMousePosition() const @@ -113,7 +115,7 @@ void UCloud9MouseController::SetCameraZoomLevel(float Value) const // ReSharper disable once CppMemberFunctionMayBeConst void UCloud9MouseController::OnCharacterMove() { ProcessCharacterView(); } -void UCloud9MouseController::ProcessCharacterView() const +void UCloud9MouseController::ProcessCharacterView() { if (let Pawn = GetCloud9Pawn(); IsValid(Pawn)) { @@ -126,7 +128,17 @@ void UCloud9MouseController::ProcessCharacterView() const true, ActorsToIgnore }; - Pawn->SetViewDirection(CursorHit); + + if (CursorHit.IsSet()) + { + LastCrosshairLocation = CursorHit->Location; + bIsLastCrosshairLocationValid = true; + Pawn->SetViewDirection(CursorHit); + } + else + { + bIsLastCrosshairLocationValid = true; + } } } } diff --git a/Source/Cloud9/Contollers/Cloud9MouseController.h b/Source/Cloud9/Contollers/Cloud9MouseController.h index dfb0d81b9..16aa6e1ab 100644 --- a/Source/Cloud9/Contollers/Cloud9MouseController.h +++ b/Source/Cloud9/Contollers/Cloud9MouseController.h @@ -67,7 +67,7 @@ class CLOUD9_API UCloud9MouseController float GetCameraZoomHeightLevel() const; void SetCameraZoomLevel(float Value) const; - void ProcessCharacterView() const; + void ProcessCharacterView(); void ProcessCameraRotation(); void ProcessCameraZoom(float DeltaTime); @@ -107,6 +107,12 @@ class CLOUD9_API UCloud9MouseController UPROPERTY(EditDefaultsOnly, Category = Smooth, meta=(AllowPrivateAccess)) float CameraZoomSmoothSpeed; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess)) + FVector LastCrosshairLocation; + + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=State, meta=(AllowPrivateAccess)) + bool bIsLastCrosshairLocationValid; + FVector2D CameraRotationBase; float TargetCameraZoomLevel; float TargetCameraZoomSpeed; diff --git a/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.cpp b/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.cpp index 7c862520c..f037b364e 100644 --- a/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.cpp +++ b/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.cpp @@ -385,7 +385,7 @@ bool ACloud9WeaponBase::ChangeState(EWeaponBond NewBond, bool Instant, bool Forc } if (let AnimComponent = Character->GetAnimationComponent(); - not Force and AnimComponent->IsAnyMontagePlaying()) + not Force and IsValid(AnimComponent) and AnimComponent->IsAnyMontagePlaying()) { log(Verbose, "[Weapon='%s' Bond='%s'] Montage is playing now", *GetName(), BOND_NAME); return false; diff --git a/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.h b/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.h index a4b94a02b..8fe6727a2 100644 --- a/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.h +++ b/Source/Cloud9/Weapon/Classes/Cloud9WeaponBase.h @@ -225,6 +225,13 @@ class CLOUD9_API ACloud9WeaponBase : public AActor return; \ } +#define WEAPON_ANIM_COMPONENT_GUARD() \ + if (not IsValid(AnimComponent)) \ + { \ + log(Warning, "[Weapon='%s'] AnimComponent isn't valid", *GetName()); \ + return; \ + } + #define WEAPON_IS_ACTION_IN_PROGRESS_GUARD() \ if (IsActionInProgress()) \ { \ diff --git a/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp b/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp index 6d78b093c..94a3e3a17 100644 --- a/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp +++ b/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp @@ -136,6 +136,9 @@ void ACloud9WeaponFirearm::Tick(float DeltaSeconds) let Character = GetOwner(); // suppose weapon has owner cus we pass bond guard let AnimComponent = Character->GetAnimationComponent(); + + WEAPON_ANIM_COMPONENT_GUARD(); + let WeaponInfo = WeaponDefinition.GetWeaponInfo(); let PoseMontages = WeaponDefinition.GetPoseMontages(Character->bIsCrouched); let CommonData = WeaponDefinition.GetCommonData(); diff --git a/Source/Cloud9/Weapon/Classes/Cloud9WeaponGrenade.cpp b/Source/Cloud9/Weapon/Classes/Cloud9WeaponGrenade.cpp index 231273874..84f7198b8 100644 --- a/Source/Cloud9/Weapon/Classes/Cloud9WeaponGrenade.cpp +++ b/Source/Cloud9/Weapon/Classes/Cloud9WeaponGrenade.cpp @@ -157,6 +157,9 @@ void ACloud9WeaponGrenade::Tick(float DeltaSeconds) let Character = GetOwner(); let AnimComponent = Character->GetAnimationComponent(); + + WEAPON_ANIM_COMPONENT_GUARD(); + let PoseMontages = WeaponDefinition.GetPoseMontages(Character->bIsCrouched); if (WeaponState.IsActionActive(EWeaponAction::Deploy)) diff --git a/Source/Cloud9/Weapon/Classes/Cloud9WeaponMelee.cpp b/Source/Cloud9/Weapon/Classes/Cloud9WeaponMelee.cpp index 73b0ed1c2..1d5f7f0e2 100644 --- a/Source/Cloud9/Weapon/Classes/Cloud9WeaponMelee.cpp +++ b/Source/Cloud9/Weapon/Classes/Cloud9WeaponMelee.cpp @@ -80,6 +80,9 @@ void ACloud9WeaponMelee::Tick(float DeltaSeconds) let Character = GetOwner(); let AnimComponent = Character->GetAnimationComponent(); + + WEAPON_ANIM_COMPONENT_GUARD(); + let WeaponInfo = WeaponDefinition.GetWeaponInfo(); let PoseMontages = WeaponDefinition.GetPoseMontages(Character->bIsCrouched);