shootergame-pickup

ShooterPickup.cpp

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "ShooterGame.h"
#include "Pickups/ShooterPickup.h"
#include "Particles/ParticleSystemComponent.h"

AShooterPickup::AShooterPickup(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    UCapsuleComponent* CollisionComp = ObjectInitializer.CreateDefaultSubobject<UCapsuleComponent>(this, TEXT("CollisionComp"));
    CollisionComp->InitCapsuleSize(40.0f, 50.0f);
    CollisionComp->SetCollisionObjectType(COLLISION_PICKUP);
    CollisionComp->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
    CollisionComp->SetCollisionResponseToAllChannels(ECR_Ignore);
    CollisionComp->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
    RootComponent = CollisionComp;

    PickupPSC = ObjectInitializer.CreateDefaultSubobject<UParticleSystemComponent>(this, TEXT("PickupFX"));
    PickupPSC->bAutoActivate = false;
    PickupPSC->bAutoDestroy = false;
    PickupPSC->SetupAttachment(RootComponent);

    RespawnTime = 10.0f;
    bIsActive = false;
    PickedUpBy = NULL;

    SetRemoteRoleForBackwardsCompat(ROLE_SimulatedProxy);
    bReplicates = true;
}

void AShooterPickup::BeginPlay()
{
    Super::BeginPlay();

    RespawnPickup();

    // register on pickup list (server only), don't care about unregistering (in FinishDestroy) - no streaming
    AShooterGameMode* GameMode = GetWorld()->GetAuthGameMode<AShooterGameMode>();
    if (GameMode)
    {
        GameMode->LevelPickups.Add(this);
    }
}

void AShooterPickup::NotifyActorBeginOverlap(class AActor* Other)
{
    Super::NotifyActorBeginOverlap(Other);
    PickupOnTouch(Cast<AShooterCharacter>(Other));
}

bool AShooterPickup::CanBePickedUp(class AShooterCharacter* TestPawn) const
{
    return TestPawn && TestPawn->IsAlive();
}

void AShooterPickup::GivePickupTo(class AShooterCharacter* Pawn)
{
}

void AShooterPickup::PickupOnTouch(class AShooterCharacter* Pawn)
{
    if (bIsActive && Pawn && Pawn->IsAlive() && !IsPendingKill())
    {
        if (CanBePickedUp(Pawn))
        {
            GivePickupTo(Pawn);
            PickedUpBy = Pawn;

            if (!IsPendingKill())
            {
                bIsActive = false;
                OnPickedUp();

                if (RespawnTime > 0.0f)
                {
                    GetWorldTimerManager().SetTimer(TimerHandle_RespawnPickup, this, &AShooterPickup::RespawnPickup, RespawnTime, false);
                }
            }
        }
    }
}

void AShooterPickup::RespawnPickup()
{
    bIsActive = true;
    PickedUpBy = NULL;
    OnRespawned();

    TSet<AActor*> OverlappingPawns;
    GetOverlappingActors(OverlappingPawns, AShooterCharacter::StaticClass());

    for (AActor* OverlappingPawn : OverlappingPawns)
    {
        PickupOnTouch(CastChecked<AShooterCharacter>(OverlappingPawn)); 
    }
}

void AShooterPickup::OnPickedUp()
{
    if (RespawningFX)
    {
        PickupPSC->SetTemplate(RespawningFX);
        PickupPSC->ActivateSystem();
    }
    else
    {
        PickupPSC->DeactivateSystem();
    }

    if (PickupSound && PickedUpBy)
    {
        UGameplayStatics::SpawnSoundAttached(PickupSound, PickedUpBy->GetRootComponent());
    }

    OnPickedUpEvent();
}

void AShooterPickup::OnRespawned()
{
    if (ActiveFX)
    {
        PickupPSC->SetTemplate(ActiveFX);
        PickupPSC->ActivateSystem();
    }
    else
    {
        PickupPSC->DeactivateSystem();
    }

    const bool bJustSpawned = CreationTime <= (GetWorld()->GetTimeSeconds() + 5.0f);
    if (RespawnSound && !bJustSpawned)
    {
        UGameplayStatics::PlaySoundAtLocation(this, RespawnSound, GetActorLocation());
    }

    OnRespawnEvent();
}

void AShooterPickup::OnRep_IsActive()
{
    if (bIsActive)
    {
        OnRespawned();
    }
    else
    {
        OnPickedUp();
    }
}

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

    DOREPLIFETIME( AShooterPickup, bIsActive );
    DOREPLIFETIME( AShooterPickup, PickedUpBy );
}

ShooterPickup_Ammo.cpp

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "ShooterGame.h"
#include "Pickups/ShooterPickup_Ammo.h"
#include "Weapons/ShooterWeapon.h"

AShooterPickup_Ammo::AShooterPickup_Ammo(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    AmmoClips = 2;
}

bool AShooterPickup_Ammo::IsForWeapon(UClass* WeaponClass)
{
    return WeaponType->IsChildOf(WeaponClass);
}

bool AShooterPickup_Ammo::CanBePickedUp(AShooterCharacter* TestPawn) const
{
    AShooterWeapon* TestWeapon = (TestPawn ? TestPawn->FindWeapon(WeaponType) : NULL);
    if (bIsActive && TestWeapon)
    {
        return TestWeapon->GetCurrentAmmo() < TestWeapon->GetMaxAmmo();
    }

    return false;
}

void AShooterPickup_Ammo::GivePickupTo(class AShooterCharacter* Pawn)
{
    AShooterWeapon* Weapon = (Pawn ? Pawn->FindWeapon(WeaponType) : NULL);
    if (Weapon)
    {
        int32 Qty = AmmoClips * Weapon->GetAmmoPerClip();
        Weapon->GiveAmmo(Qty);

        // Fire event for collected ammo
        if (Pawn)
        {
            const auto Events = Online::GetEventsInterface();
            const auto Identity = Online::GetIdentityInterface();

            if (Events.IsValid() && Identity.IsValid())
            {                           
                AShooterPlayerController* PC = Cast<AShooterPlayerController>(Pawn->Controller);
                if (PC)
                {
                    ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PC->Player);

                    if (LocalPlayer)
                    {
                        const int32 UserIndex = LocalPlayer->GetControllerId();
                        TSharedPtr<const FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex);           
                        if (UniqueID.IsValid())
                        {
                            FVector Location = Pawn->GetActorLocation();

                            FOnlineEventParms Params;       

                            Params.Add( TEXT( "SectionId" ), FVariantData( (int32)0 ) ); // unused
                            Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) ); // @todo determine game mode (ffa v tdm)
                            Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) ); // unused

                            Params.Add( TEXT( "ItemId" ), FVariantData( (int32)Weapon->GetAmmoType() + 1 ) ); // @todo come up with a better way to determine item id, currently health is 0 and ammo counts from 1
                            Params.Add( TEXT( "AcquisitionMethodId" ), FVariantData( (int32)0 ) ); // unused
                            Params.Add( TEXT( "LocationX" ), FVariantData( Location.X ) );
                            Params.Add( TEXT( "LocationY" ), FVariantData( Location.Y ) );
                            Params.Add( TEXT( "LocationZ" ), FVariantData( Location.Z ) );
                            Params.Add( TEXT( "ItemQty" ), FVariantData( (int32)Qty ) );        

                            Events->TriggerEvent(*UniqueID, TEXT("CollectPowerup"), Params);
                        }
                    }
                }
            }
        }
    }
}

ShooterPickup_Health.cpp

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "ShooterGame.h"
#include "Pickups/ShooterPickup_Health.h"

AShooterPickup_Health::AShooterPickup_Health(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
    Health = 50;
}

bool AShooterPickup_Health::CanBePickedUp(class AShooterCharacter* TestPawn) const
{
    return TestPawn && (TestPawn->Health < TestPawn->GetMaxHealth());
}

void AShooterPickup_Health::GivePickupTo(class AShooterCharacter* Pawn)
{
    if (Pawn)
    {
        Pawn->Health = FMath::Min(FMath::TruncToInt(Pawn->Health) + Health, Pawn->GetMaxHealth());

        // Fire event for collected health
        const auto Events = Online::GetEventsInterface();
        const auto Identity = Online::GetIdentityInterface();

        if (Events.IsValid() && Identity.IsValid())
        {                           
            AShooterPlayerController* PC = Cast<AShooterPlayerController>(Pawn->Controller);
            if (PC)
            {
                ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PC->Player);

                if (LocalPlayer)
                {
                    const int32 UserIndex = LocalPlayer->GetControllerId();
                    TSharedPtr<const FUniqueNetId> UniqueID = Identity->GetUniquePlayerId(UserIndex);           
                    if (UniqueID.IsValid())
                    {
                        FVector Location = Pawn->GetActorLocation();

                        FOnlineEventParms Params;       

                        Params.Add( TEXT( "SectionId" ), FVariantData( (int32)0 ) ); // unused
                        Params.Add( TEXT( "GameplayModeId" ), FVariantData( (int32)1 ) ); // @todo determine game mode (ffa v tdm)
                        Params.Add( TEXT( "DifficultyLevelId" ), FVariantData( (int32)0 ) ); // unused

                        Params.Add( TEXT( "ItemId" ), FVariantData( (int32)0 ) ); // @todo come up with a better way to determine item id, currently health is 0 and ammo counts from 1
                        Params.Add( TEXT( "AcquisitionMethodId" ), FVariantData( (int32)0 ) ); // unused
                        Params.Add( TEXT( "LocationX" ), FVariantData( Location.X ) );
                        Params.Add( TEXT( "LocationY" ), FVariantData( Location.Y ) );
                        Params.Add( TEXT( "LocationZ" ), FVariantData( Location.Z ) );
                        Params.Add( TEXT( "ItemQty" ), FVariantData( (int32)Health ) );         

                        Events->TriggerEvent(*UniqueID, TEXT("CollectPowerup"), Params);
                    }
                }
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值